# Sam Pursuits **A personal pursuits portfolio — a React showcase of interests, projects, and the work outside the day job.** An interactive single-page application that presents personal pursuits — gardening, electronics, tinkering, and life projects — as a curated, editorial experience. Built to demonstrate front-end architecture, component design, and modern React patterns. ## What it is A portfolio site that showcases what I build and explore beyond professional work. Each pursuit gets a dedicated page with rich content blocks, stats, and links, presented in a clean, motion-rich interface. ## Tech stack | Layer | Technology | |-------|-----------| | Framework | React 19 | | Build | Vite 6 | | Styling | Tailwind CSS 4 (via `@tailwindcss/vite`) | | Animation | Motion 12 (framer-motion successor) | | Routing | React Router 7 | | Icons | lucide-react | | Language | TypeScript | ## Architecture & design patterns - **Component-driven design** — small, focused components (`PursuitCard`, `PursuitHero`, `SectionCard`, `StatBadge`, `ExternalLinkCard`) composed into pages - **Data-driven content** — all content lives in typed data modules (`pursuitsData.ts`, `navItems.ts`), so adding a pursuit is pure data entry, no new components - **Reusable layout shell** — shared `Layout` + `PageHeader` provide consistent page chrome - **Reusable content blocks** — `ContentBlocks` renders heterogeneous content (prose, stats, media, links) from structured data - **Horizontal tabs** — `HorizontalTabs` for sub-navigation within a page - **AI chat box** — embedded assistant interface (`AiChatBox`) for interactive engagement - **Fade/slide animation patterns** — motion variants (`hidden` → `show` with staggered children) for consistent page transitions - **Route-based pages** — React Router for multi-page feel within an SPA ## Pages | Route | Purpose | |-------|---------| | `/` | Home — hero + pursuit index | | `/interests` | Interest areas overview | | `/pursuits/:id` | Individual pursuit deep-dive | | `/ai-chat` | Interactive AI assistant | | `/contact` | Contact + links | ## Standards - TypeScript strict mode - Semantic HTML with accessible landmarks - Tailwind utility-first styling with design tokens - Fully responsive (mobile → desktop) - Performance-minded (Vite code-splitting, no heavy dependencies) ## Getting started ```bash npm install npm run dev # development server npm run build # production build npm run preview # preview production build ``` ## Structure ``` src/ ├── components/ # Reusable UI components │ ├── Layout.tsx / PageHeader.tsx / SectionCard.tsx │ ├── PursuitCard.tsx / PursuitHero.tsx / StatBadge.tsx │ ├── ContentBlocks.tsx / HorizontalTabs.tsx / ExternalLinkCard.tsx │ └── AiChatBox.tsx ├── data/ # Typed content (pursuitsData.ts, navItems.ts) ├── pages/ # Route components (Home, Interests, PursuitPage, AiChat, Contact) ├── App.tsx # Router + app shell └── main.tsx # Entry point ``` --- *One of several portfolio sites in the Sam Rolfe showcase family — see [sam-developer](https://gitea.lab.audasmedia.com.au/sam/sam-developer), [sam-devops](https://gitea.lab.audasmedia.com.au/sam/sam-devops), and [sam-iot-electronics](https://gitea.lab.audasmedia.com.au/sam/sam-iot-electronics).*