Imported from swift456/coruscating-creponne-9e8364 (
AGENTS.md). Install upstream withnpx skills add swift456/coruscating-creponne-9e8364. Copyright stays with the author.
AGENTS.md
Overview of the project structure for developers and AI agents working on this codebase.
Project Overview
A single-page brochure site for Edwards Health, a real family-run mobile private healthcare service based in Penyffordd, North Wales. Built with TanStack Start and deployed on Netlify.
Tech Stack
| Layer | Technology |
|---|---|
| Framework | TanStack Start |
| Frontend | React 19, TanStack Router v1 |
| Build | Vite 7 |
| Styling | Tailwind CSS 4 (CSS-first @theme config, no tailwind.config.js) |
| Icons | lucide-react |
| Forms | Netlify Forms |
| Language | TypeScript 5.9 |
| Deployment | Netlify |
Directory Structure
├── public
│ ├── favicon.ico
│ └── __forms.html # Static skeleton so Netlify's build bot detects the contact form (see below)
├── src
│ ├── components
│ │ ├── ContactForm.tsx # AJAX-submitted Netlify Form ("consultation-request")
│ │ └── ScrollReveal.tsx # IntersectionObserver wrapper adding a fade/rise-in transition on scroll
│ ├── routes
│ │ ├── __root.tsx # Root layout: fonts, meta, grain overlay
│ │ └── index.tsx # The entire brochure page — nav, hero, and all sections
│ ├── router.tsx # TanStack Router setup
│ └── styles.css # Tailwind import, @theme tokens (colors/fonts), animation keyframes
├── netlify.toml # Build command (vite build), publish dir (dist/client), dev server config
├── package.json
├── tsconfig.json # `@/*` path alias for `src/*`
└── vite.config.ts
Key Concepts
Single-page brochure layout
src/routes/index.tsx renders every section of the page as its own component (Hero, About, WhyChooseUs, Coverage, Promise, ContactSection, Footer), all composed inside HomePage. There is intentionally only one route — this is a marketing brochure, not a multi-page app. Navigation links are in-page anchors (#about, #why-us, etc.), not router routes.
Embeds
Coverage embeds a Google Maps iframe centred on the clinic's coverage area. It uses a q= search-query URL rather than an address-pin embed, so it can be pointed at a new area by editing the src string directly (see the comment above the iframe in index.tsx).
Netlify Forms in TanStack Start
Because TanStack Start renders the form client-side, Netlify's build-time HTML scanner can't see it. public/__forms.html is a hidden static duplicate of the form that exists purely so Netlify registers the consultation-request form name at build time. ContactForm.tsx submits via fetch('/__forms.html', ...) (not /) so the POST reaches Netlify's form-processing middleware instead of being swallowed by the SSR catch-all. Forms only work on a deployed site, not local dev.
Design tokens
Colors and fonts are defined once as CSS custom properties in styles.css via Tailwind 4's @theme block (--color-linen, --color-sage, --color-terracotta, --font-display = Fraunces, --font-body = Karla), then referenced as ordinary Tailwind utilities (bg-linen, text-sage-dark, font-display). Change the palette or fonts in one place.
Development Commands
npm run dev # Start dev server (vite dev --port 3000)
npm run build # Production build
Conventions
- Components: PascalCase, one section per component in
index.tsx - Import paths use the
@/alias forsrc/* - Scroll-in reveals go through the shared
<ScrollReveal>wrapper rather than ad hoc IntersectionObserver code