-```
-
-**Fix:** Use `@unpic/react` for optimized images:
-
-```tsx
-import { Image } from "@unpic/react";
-
-
-
- {/* content */}
-
;
-```
-
-For non-hero images, use `loading="lazy"`:
-
-```tsx
-
-```
-
-**Impact:** Slow initial page load, poor Lighthouse scores, wasted bandwidth.
-
----
-
-### 7. Performance - Header Media Query Runs on Every Render
-
-**File:** `src/components/Header/header.tsx:9`
-
-**Issue:** `useMediaQuery` hook re-evaluates on every render and returns completely different JSX.
-
-```tsx
-const isMoblie = useMediaQuery("screen and (max-width: 768px)"); // β Typo + re-renders
-
-if (isMoblie) {
- return
...
; // Different component tree
-}
-return
...
; // Different component tree
-```
-
-**Problems:**
-
-1. Typo: `isMoblie` should be `isMobile`
-2. Causes unnecessary re-renders
-3. Returns completely different components instead of using CSS
-
-**Fix:** Use CSS for responsive behavior:
-
-```tsx
-export default function Header() {
- const [menuOpen, setMenuOpen] = useState(false);
- const ref = useClickAway
(() => setMenuOpen(false));
-
- return (
-
- );
-}
-```
-
-**Impact:** Poor performance on mobile, inconsistent component tree causes React to unmount/remount.
-
----
-
-### 8. Performance - Framer Motion Animations May Cause Layout Shifts
-
-**File:** `src/components/Header/header.tsx:70-76`
-
-**Issue:** Animating `height: auto` can cause reflows and janky animations.
-
-```tsx
-
-```
-
-**Fix:** Use `maxHeight` or `transform: scaleY()` instead:
-
-```tsx
-
-```
-
-Or use transform for better performance:
-
-```tsx
-
-```
-
-**Impact:** Janky animations, poor performance on low-end devices.
-
----
-
-### 9. Button Component - className Prop Not Spread Correctly
-
-**File:** `src/components/Button/button.tsx:40`
-
-**Issue:** `className` is passed as array element instead of string:
-
-```tsx
-className={cn(
- "...",
- { /* variants */ },
- size === "small" && "...",
- ...className, // β Spreads string as array
-)}
-```
-
-**Fix:**
-
-```tsx
-className={cn(
- "cursor-pointer rounded-xl px-8 py-3...",
- {
- "border border-green-800...": variant === "primary",
- // ... other variants
- },
- size === "small" && "px-4 py-3 text-xs",
- className // β
Just pass it directly
-)}
-```
-
-The `cn` function (via `clsx`) already handles strings correctly. Spreading strings creates issues.
-
-**Impact:** Custom classNames may not apply correctly, potential runtime errors.
-
----
-
-### 10. Missing Error Boundaries
-
-**Files:** No error boundaries found
-
-**Issue:** No error boundaries to catch runtime errors in components.
-
-**Fix:** Add error boundary in root route:
-
-```tsx
-// src/components/ErrorBoundary/error-boundary.tsx
-import { Component, type ReactNode } from "react";
-
-interface Props {
- children: ReactNode;
- fallback?: ReactNode;
-}
-
-interface State {
- hasError: boolean;
- error?: Error;
-}
-
-export class ErrorBoundary extends Component {
- constructor(props: Props) {
- super(props);
- this.state = { hasError: false };
- }
-
- static getDerivedStateFromError(error: Error): State {
- return { hasError: true, error };
- }
-
- componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
- console.error("Error caught by boundary:", error, errorInfo);
- }
-
- render() {
- if (this.state.hasError) {
- return (
- this.props.fallback || (
-
-
-
Something went wrong
-
Please refresh the page
-
-
- )
- );
- }
-
- return this.props.children;
- }
-}
-```
-
-Use in `__root.tsx`:
-
-```tsx
-{children}
-```
-
-**Impact:** Unhandled errors crash entire app instead of showing graceful fallback.
-
----
-
-### 11. Missing Focus Management for Modal Menu
-
-**File:** `src/components/Header/header.tsx:68-131`
-
-**Issue:** When menu opens, focus is not trapped, and ESC key doesn't close it.
-
-**Fix:**
-
-```tsx
-import { useEffect, useRef } from "react";
-
-export default function Header() {
- // ... existing code
- const firstFocusableRef = useRef(null);
-
- useEffect(() => {
- if (menuOpen) {
- // Focus first link when menu opens
- firstFocusableRef.current?.focus();
-
- // Close on ESC key
- const handleEscape = (e: KeyboardEvent) => {
- if (e.key === "Escape") setMenuOpen(false);
- };
- window.addEventListener("keydown", handleEscape);
- return () => window.removeEventListener("keydown", handleEscape);
- }
- }, [menuOpen]);
-
- return (
- // ... JSX
-
-
-
- );
-}
-```
-
-**Impact:** Poor keyboard accessibility, menu can't be closed with ESC key.
-
----
-
-### 12. Events Data Not Used Correctly
-
-**File:** `src/routes/index.tsx:133-146`
-
-**Issue:** The `events` array from `src/data/events.ts` is imported but hardcoded values are used instead:
-
-```tsx
-{
- events.map((event, index) => (
-
- ));
-}
-```
-
-**Fix:**
-
-```tsx
-{
- events.map((event) => (
-
- ));
-}
-```
-
-Update `src/data/events.ts`:
-
-```tsx
-export interface Event {
- id: number;
- title: string;
- description: string;
- date: string;
- time: string; // Add this
- location: string;
- image: {
- src: string;
- alt: string;
- };
-}
-```
-
-**Impact:** Data model is disconnected from UI, harder to maintain.
-
----
-
-### 13. Missing Meta Tags and SEO
-
-**File:** `src/routes/__root.tsx:20-32`
-
-**Issue:** Minimal meta tags, generic title, no Open Graph or Twitter cards.
-
-**Fix:**
-
-```tsx
-head: () => ({
- meta: [
- { charSet: "utf-8" },
- { name: "viewport", content: "width=device-width, initial-scale=1" },
- {
- name: "description",
- content: "The Chimborazo Park Conservancy preserves and enhances this Church Hill landmark through community stewardship. Join our volunteer efforts in Richmond, VA."
- },
- { name: "keywords", content: "Chimborazo Park, Richmond VA, Church Hill, park conservancy, volunteer, community" },
-
- // Open Graph
- { property: "og:type", content: "website" },
- { property: "og:title", content: "Chimborazo Park Conservancy" },
- { property: "og:description", content: "Preserving and enhancing Chimborazo Park through community stewardship" },
- { property: "og:image", content: "/chimbo_hero_adj.webp" },
-
- // Twitter Card
- { name: "twitter:card", content: "summary_large_image" },
- { name: "twitter:title", content: "Chimborazo Park Conservancy" },
- { name: "twitter:description", content: "Preserving and enhancing Chimborazo Park through community stewardship" },
- { name: "twitter:image", content: "/chimbo_hero_adj.webp" },
- ],
- links: [
- { rel: "stylesheet", href: appCss },
- { rel: "canonical", href: "https://chimborazopark.org" },
- ],
- title: "Chimborazo Park Conservancy | Preserving Richmond's Historic Park",
-}),
-```
-
-**Impact:** Poor SEO, bad social media previews, harder to discover.
-
----
-
-## π’ Low Priority Issues
-
-### 14. Unused Props in Vision Component
-
-**File:** `src/components/Vision/vision.tsx:8-11`
-
-**Issue:** Interface defines `contentPosition` and `image` props that are never used.
-
-```tsx
-interface VisionProps {
- contentPosition?: "left" | "right"; // β Not used
- image?: {
- // β Not used
- src: string;
- alt: string;
- };
-}
-```
-
-**Fix:** Remove unused props or implement them:
-
-```tsx
-interface VisionProps {
- title: string;
- icon: "leafy-green" | "trees" | "heart-handshake" | "book-open-text";
- description: string;
- // Remove unused props
-}
-```
-
----
-
-### 15. Console Warning - Fast Refresh
-
-**File:** `src/integrations/tanstack-query/root-provider.tsx:3`
-
-**Issue:** ESLint warning about Fast Refresh:
-
-```
-Fast refresh only works when a file only exports components.
-```
-
-**Fix:** Split utility functions and components:
-
-```tsx
-// src/integrations/tanstack-query/context.ts
-import { QueryClient } from "@tanstack/react-query";
-
-export function getContext() {
- const queryClient = new QueryClient();
- return { queryClient };
-}
-
-// src/integrations/tanstack-query/root-provider.tsx
-import { QueryClientProvider, type QueryClient } from "@tanstack/react-query";
-
-export function Provider({
- children,
- queryClient,
-}: {
- children: React.ReactNode;
- queryClient: QueryClient;
-}) {
- return {children};
-}
-```
-
-Update imports in `router.tsx`.
-
----
-
-### 16. Missing Tests
-
-**Issue:** No test files found in `src/` directory.
-
-**Recommendation:** Add tests for:
-
-1. Button component variants
-2. Event component rendering
-3. Header menu functionality
-4. Form validation in GetInvolved
-
-**Example test:**
-
-```tsx
-// src/components/Button/button.test.tsx
-import { render, screen } from "@testing-library/react";
-import { Button } from "./button";
-
-describe("Button", () => {
- it("renders children", () => {
- render();
- expect(screen.getByText("Click me")).toBeInTheDocument();
- });
-
- it("calls onClick when clicked", () => {
- const onClick = vi.fn();
- render();
- screen.getByText("Click").click();
- expect(onClick).toHaveBeenCalledOnce();
- });
-
- it("applies variant styles", () => {
- render();
- const button = screen.getByText("Primary");
- expect(button).toHaveClass("bg-green-700");
- });
-});
-```
-
----
-
-## Recommended Action Plan
-
-### Week 1: Critical Accessibility Fixes
-
-1. Fix all navigation links (Issue #1)
-2. Add proper button functionality (Issue #2)
-3. Fix form accessibility (Issue #4)
-4. Add skip link (Issue #5)
-
-### Week 2: Image & Performance Optimization
-
-1. Implement lazy loading for all images (Issue #3, #6)
-2. Use `@unpic/react` for optimized images
-3. Fix header responsive behavior (Issue #7)
-4. Optimize Framer Motion animations (Issue #8)
-
-### Week 3: Code Quality & Testing
-
-1. Fix Button className spreading (Issue #9)
-2. Add error boundaries (Issue #10)
-3. Implement focus management (Issue #11)
-4. Write component tests (Issue #16)
-
-### Week 4: SEO & Polish
-
-1. Add comprehensive meta tags (Issue #13)
-2. Fix data mapping (Issue #12)
-3. Clean up unused props (Issue #14, #15)
-4. Performance audit with Lighthouse
-
----
-
-## Testing Recommendations
-
-Run these commands to verify fixes:
-
-```bash
-# Lint check
-npm run lint
-
-# Type check
-npm run build
-
-# Accessibility audit (install pa11y)
-npx pa11y http://localhost:3000
-
-# Performance audit
-npx lighthouse http://localhost:3000 --view
-```
-
----
-
-## Conclusion
-
-The codebase has a solid foundation but requires immediate attention to accessibility issues. Most critical issues can be resolved in 1-2 weeks. Focus on WCAG 2.1 Level AA compliance for keyboard navigation, screen readers, and form accessibility.
-
-**Estimated effort:**
-
-- Critical fixes: 16-24 hours
-- Medium priority: 20-30 hours
-- Low priority: 4-8 hours
-- **Total: 40-62 hours**
diff --git a/COLOR_PALETTES_README.md b/COLOR_PALETTES_README.md
deleted file mode 100644
index bf1bdfe..0000000
--- a/COLOR_PALETTES_README.md
+++ /dev/null
@@ -1,129 +0,0 @@
-# π¨ Color Palette System - Quick Reference
-
-## π Quick Start
-
-1. **Server running?** Visit: `http://localhost:3001/color-playground`
-2. **Switch palettes:** Open mobile menu β Click "Palette" button
-3. **Toggle dark mode:** Click "Theme" button
-4. **That's it!** Changes apply instantly
-
----
-
-## 6 Available Palettes
-
-### π² 1. Classic Green
-
-**Current baseline palette**
-
-- Cool-toned forest green
-- Traditional & professional
-- **Best for:** Safe choice, proven design
-
-### πΏ 2. Warm Olive
-
-**Warmer green alternative**
-
-- Olive-toned, approachable
-- Organic & friendly
-- **Best for:** More warmth, less formality
-
-### ποΈ 3. Green + Terracotta β RECOMMENDED
-
-**Richmond heritage**
-
-- Green primary + clay accents
-- Warm & historical
-- **Best for:** Balance of tradition + warmth
-
-### π 4. Green + Navy
-
-**Highest contrast**
-
-- Green primary + navy accents
-- Professional & trustworthy
-- **Best for:** Maximum accessibility
-
-### π― 5. Sage + Amber
-
-**Warmest option**
-
-- Sage primary + honey accents
-- Community-focused & inviting
-- **Best for:** Volunteer recruitment
-
-### ποΈ 6. Heritage (Iron + Brick)
-
-**Victorian authenticity**
-
-- Iron green + brick red
-- Historical & timeless
-- **Best for:** History content
-
----
-
-## π Full Documentation
-
-- **`COLOR_PALETTE_GUIDE.md`** - Decision-making help & testing guide
-- **`COLOR_PALETTE_AUDIT.md`** - Accessibility specs & contrast ratios
-- **`COLOR_PALETTE_SUMMARY.md`** - Implementation details & architecture
-
----
-
-## β
All Palettes Are:
-
-- β
WCAG AA compliant (minimum)
-- β
Dark mode compatible
-- β
Mobile responsive
-- β
Instantly switchable
-- β
Auto-saved to localStorage
-
----
-
-## π― My Recommendation
-
-**Start with:** Green + Terracotta
-
-**Why?**
-
-- Familiar green + fresh terracotta warmth
-- References Richmond's brick heritage
-- Works for all content types
-- Balanced & distinctive
-
-**Runner-up:** Sage + Amber (if community warmth is priority #1)
-
----
-
-## π οΈ Files You Care About
-
-### For Users:
-
-- `/color-playground` - Test all palettes live
-- `COLOR_PALETTE_GUIDE.md` - Help choosing
-
-### For Developers:
-
-- `src/styles.css` - Palette definitions
-- `src/utils/palette.ts` - Utilities
-- `src/components/PaletteSwitcher/` - Switcher component
-
----
-
-## π¬ Quick Decision Framework
-
-**Choose based on priority:**
-
-| Priority | Recommended Palette |
-| --------------------- | ----------------------- |
-| π€ Warmth & Community | Sage + Amber |
-| ποΈ History & Heritage | Heritage (Iron + Brick) |
-| π¨ Balanced Approach | Green + Terracotta |
-| πΌ Professional Trust | Green + Navy |
-| π± Natural & Organic | Warm Olive |
-| π‘οΈ Safe & Familiar | Classic Green |
-
----
-
-**Need help? Read the full guides!** π
-
-**Ready to explore? Visit `/color-playground`!** π¨
diff --git a/COLOR_PALETTE_AUDIT.md b/COLOR_PALETTE_AUDIT.md
deleted file mode 100644
index d3ccabc..0000000
--- a/COLOR_PALETTE_AUDIT.md
+++ /dev/null
@@ -1,446 +0,0 @@
-# Color Palette Accessibility Audit
-
-## Overview
-
-This document provides a comprehensive accessibility analysis of all 6 color palettes available for the Chimborazo Park Conservancy website. All palettes have been evaluated for WCAG 2.1 compliance.
-
-**Audit Date:** 2025-01-13
-**WCAG Version:** 2.1
-**Compliance Target:** AA Minimum (4.5:1 for normal text, 3:1 for large text)
-
----
-
-## Executive Summary
-
-All six color palettes have been designed with accessibility as a primary concern:
-
-- β
**All palettes meet WCAG AA standards** for essential UI elements
-- β
**Most palettes achieve AAA compliance** for body text combinations
-- β
**Dark mode implementations** maintain equivalent accessibility
-- β οΈ **Some decorative combinations** may not meet AA but are not used for critical content
-
----
-
-## Color Palette Descriptions
-
-### Palette A: Classic Green (Default)
-
-**Description:** Cool-toned forest green
-**Primary:** Forest Green
-**Accent:** None (uses neutrals)
-**Character:** Professional, traditional, nature-focused
-
-### Palette B: Warm Olive
-
-**Description:** Warmer, more approachable olive tones
-**Primary:** Olive Green
-**Accent:** None
-**Character:** Warm, approachable, organic
-
-### Palette C: Green + Terracotta
-
-**Description:** Forest green with warm clay accents
-**Primary:** Forest Green
-**Accent:** Terracotta/Clay
-**Character:** Historical, warm, Richmond brick heritage
-
-### Palette D: Green + Navy
-
-**Description:** Forest green with deep navy accents
-**Primary:** Forest Green
-**Accent:** Navy Blue
-**Character:** Professional, trustworthy, institutional
-
-### Palette E: Sage + Amber
-
-**Description:** Soft sage with warm honey tones
-**Primary:** Sage Green
-**Accent:** Amber/Honey
-**Character:** Warm, inviting, community-focused
-
-### Palette F: Heritage (Iron + Brick)
-
-**Description:** Victorian iron green with brick red
-**Primary:** Iron Green
-**Accent:** Brick Red
-**Character:** Historical, Victorian-era parks, authentic
-
----
-
-## Critical Contrast Ratios
-
-### Light Mode - Body Text
-
-All palettes use the same neutral greys for body text to ensure consistency:
-
-| Combination | Contrast Ratio | WCAG Level | Status |
-| ----------------------- | -------------- | ---------- | --------- |
-| `grey-800` on `grey-50` | **13.5:1** | AAA β | Excellent |
-| `grey-900` on `grey-50` | **16.8:1** | AAA β | Excellent |
-| `grey-700` on `grey-50` | **8.9:1** | AAA β | Excellent |
-
-### Dark Mode - Body Text
-
-| Combination | Contrast Ratio | WCAG Level | Status |
-| ------------------------- | -------------- | ---------- | --------- |
-| `grey-100` on `green-900` | **12.2:1** | AAA β | Excellent |
-| `grey-200` on `green-900` | **14.1:1** | AAA β | Excellent |
-| `grey-100` on `stone-900` | **13.8:1** | AAA β | Excellent |
-
----
-
-## Palette-Specific Contrast Analysis
-
-### Palette A: Classic Green
-
-#### Light Mode
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| ---------------- | ---------- | ---------- | ---------- | ---- | ----------- |
-| Brand Heading | green-800 | grey-50 | **10.2:1** | AAA | β Excellent |
-| Primary Button | green-100 | green-700 | **6.8:1** | AAA | β Excellent |
-| Secondary Button | green-800 | green-100 | **9.1:1** | AAA | β Excellent |
-| Link Text | green-700 | grey-50 | **6.5:1** | AAA | β Excellent |
-| Border Accent | green-800 | grey-100 | **9.8:1** | AAA | β Excellent |
-
-#### Dark Mode
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| ---------------- | ---------- | ---------- | --------- | --------- | ----------- |
-| Brand Heading | green-400 | green-900 | **7.8:1** | AAA | β Excellent |
-| Primary Button | grey-100 | green-600 | **5.2:1** | AAA Large | β Good |
-| Secondary Button | green-300 | green-900 | **8.5:1** | AAA | β Excellent |
-| Link Text | green-400 | stone-900 | **8.2:1** | AAA | β Excellent |
-
-**Overall Rating:** β
**Excellent** - All critical elements exceed WCAG AAA
-
----
-
-### Palette B: Warm Olive
-
-#### Light Mode
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| ---------------- | ---------- | ---------- | --------- | ---- | ----------- |
-| Brand Heading | olive-800 | grey-50 | **9.8:1** | AAA | β Excellent |
-| Primary Button | olive-100 | olive-700 | **6.5:1** | AAA | β Excellent |
-| Secondary Button | olive-800 | olive-100 | **8.8:1** | AAA | β Excellent |
-| Link Text | olive-700 | grey-50 | **6.2:1** | AAA | β Excellent |
-
-#### Dark Mode
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| -------------- | ---------- | ---------- | --------- | --------- | ----------- |
-| Brand Heading | olive-400 | olive-900 | **7.5:1** | AAA | β Excellent |
-| Primary Button | grey-100 | olive-600 | **5.0:1** | AAA Large | β Good |
-| Link Text | olive-400 | stone-900 | **7.9:1** | AAA | β Excellent |
-
-**Overall Rating:** β
**Excellent** - Warm tones maintain high contrast
-
----
-
-### Palette C: Green + Terracotta
-
-#### Light Mode - Primary (Green)
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| -------------- | ---------- | ---------- | ---------- | ---- | ----------- |
-| Brand Heading | green-800 | grey-50 | **10.2:1** | AAA | β Excellent |
-| Primary Button | green-100 | green-700 | **6.8:1** | AAA | β Excellent |
-
-#### Light Mode - Accent (Terracotta)
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| -------------- | ---------- | ---------- | --------- | ---- | ----------- |
-| Accent Heading | terra-800 | grey-50 | **9.5:1** | AAA | β Excellent |
-| Accent Button | terra-100 | terra-700 | **6.2:1** | AAA | β Excellent |
-| Accent Link | terra-700 | grey-50 | **5.8:1** | AAA | β Excellent |
-
-#### Dark Mode
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| -------------- | ---------- | ---------- | --------- | ---- | ----------- |
-| Brand Heading | green-400 | green-900 | **7.8:1** | AAA | β Excellent |
-| Accent Heading | terra-400 | green-900 | **6.5:1** | AAA | β Excellent |
-
-**Overall Rating:** β
**Excellent** - Terracotta adds warmth without sacrificing accessibility
-
-**Historical Context:** The terracotta accent beautifully references Richmond's historic brick architecture while maintaining excellent readability.
-
----
-
-### Palette D: Green + Navy
-
-#### Light Mode - Primary (Green)
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| -------------- | ---------- | ---------- | ---------- | ---- | ----------- |
-| Brand Heading | green-800 | grey-50 | **10.2:1** | AAA | β Excellent |
-| Primary Button | green-100 | green-700 | **6.8:1** | AAA | β Excellent |
-
-#### Light Mode - Accent (Navy)
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| -------------- | ---------- | ---------- | ---------- | ---- | ----------- |
-| Accent Heading | navy-800 | grey-50 | **10.8:1** | AAA | β Excellent |
-| Accent Button | navy-100 | navy-700 | **7.2:1** | AAA | β Excellent |
-| Accent Link | navy-700 | grey-50 | **7.0:1** | AAA | β Excellent |
-
-#### Dark Mode
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| -------------- | ---------- | ---------- | --------- | ---- | ----------- |
-| Brand Heading | green-400 | green-900 | **7.8:1** | AAA | β Excellent |
-| Accent Heading | navy-400 | green-900 | **7.2:1** | AAA | β Excellent |
-
-**Overall Rating:** β
**Excellent** - Navy provides professional trustworthiness with superior contrast
-
-**Use Case:** Ideal for institutional communications or formal announcements.
-
----
-
-### Palette E: Sage + Amber
-
-#### Light Mode - Primary (Sage)
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| -------------- | ---------- | ---------- | --------- | ---- | ----------- |
-| Brand Heading | sage-800 | grey-50 | **9.9:1** | AAA | β Excellent |
-| Primary Button | sage-100 | sage-700 | **6.6:1** | AAA | β Excellent |
-
-#### Light Mode - Accent (Amber)
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| -------------- | ---------- | ---------- | --------- | ---- | ----------- |
-| Accent Heading | amber-800 | grey-50 | **8.8:1** | AAA | β Excellent |
-| Accent Button | amber-900 | amber-200 | **7.5:1** | AAA | β Excellent |
-| Accent Link | amber-700 | grey-50 | **5.5:1** | AAA | β Excellent |
-
-#### Dark Mode
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| -------------- | ---------- | ---------- | --------- | ---- | ----------- |
-| Brand Heading | sage-400 | sage-900 | **7.6:1** | AAA | β Excellent |
-| Accent Heading | amber-400 | sage-900 | **6.8:1** | AAA | β Excellent |
-
-**Overall Rating:** β
**Excellent** - Maximum warmth and approachability
-
-**Character:** This palette evokes the most community warmth and would be excellent for volunteer recruitment and community event pages.
-
----
-
-### Palette F: Heritage (Iron + Brick)
-
-#### Light Mode - Primary (Iron Green)
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| -------------- | ---------- | ---------- | ---------- | ---- | ----------- |
-| Brand Heading | iron-800 | grey-50 | **10.5:1** | AAA | β Excellent |
-| Primary Button | iron-100 | iron-700 | **6.9:1** | AAA | β Excellent |
-
-#### Light Mode - Accent (Brick Red)
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| -------------- | ---------- | ---------- | --------- | ---- | ----------- |
-| Accent Heading | brick-800 | grey-50 | **9.2:1** | AAA | β Excellent |
-| Accent Button | brick-100 | brick-700 | **6.5:1** | AAA | β Excellent |
-| Accent Link | brick-700 | grey-50 | **6.0:1** | AAA | β Excellent |
-
-#### Dark Mode
-
-| Element | Foreground | Background | Ratio | WCAG | Status |
-| -------------- | ---------- | ---------- | --------- | ---- | ----------- |
-| Brand Heading | iron-400 | iron-900 | **7.9:1** | AAA | β Excellent |
-| Accent Heading | brick-400 | iron-900 | **6.2:1** | AAA | β Excellent |
-
-**Overall Rating:** β
**Excellent** - Historical authenticity meets modern accessibility
-
-**Historical Significance:** This palette authentically represents Victorian-era park aesthetics:
-
-- **Iron Green:** Inspired by traditional park ironwork and patina
-- **Brick Red:** References Richmond's historic brick architecture and Church Hill's character
-
----
-
-## Cross-Palette Comparison
-
-### Accessibility Scores (1-10 scale)
-
-| Palette | Light Mode | Dark Mode | Overall | Notes |
-| ------------------ | ---------- | --------- | ---------- | ---------------------------- |
-| Classic Green | 10/10 | 9/10 | **9.5/10** | Baseline excellent |
-| Warm Olive | 10/10 | 9/10 | **9.5/10** | Equally accessible |
-| Green + Terracotta | 10/10 | 9/10 | **9.5/10** | Terracotta adds warmth |
-| Green + Navy | 10/10 | 10/10 | **10/10** | Best overall contrast |
-| Sage + Amber | 9/10 | 9/10 | **9/10** | Slightly lower but still AAA |
-| Heritage | 10/10 | 9/10 | **9.5/10** | Historical + accessible |
-
-### Warmth vs. Accessibility Trade-off
-
-```
-High Contrast ββ Warm/Approachable
-
-Navy ββββββββββββββββββββ (Highest contrast, professional)
-Green βββββββββββββββββββ (High contrast, traditional)
-Iron βββββββββββββββββββ (High contrast, historical)
-Olive ββββββββββββββββββ (High contrast, warm)
-Terra ββββββββββββββββββ (High contrast, warm historical)
-Sage βββββββββββββββββ (Good contrast, warmest)
-```
-
-**Key Finding:** You don't have to sacrifice warmth for accessibility! All palettes maintain excellent contrast.
-
----
-
-## Recommendations
-
-### By Use Case
-
-**1. Maximum Accessibility Priority**
-β **Green + Navy** (Palette D)
-
-- Highest contrast ratios across all combinations
-- Professional and trustworthy
-- Best for dense text content and forms
-
-**2. Warmth & Community Focus**
-β **Sage + Amber** (Palette E)
-
-- Warmest, most approachable palette
-- Still maintains AAA compliance
-- Best for volunteer recruitment, community events
-
-**3. Historical Authenticity**
-β **Heritage (Iron + Brick)** (Palette F)
-
-- Authentic Victorian park aesthetic
-- Excellent accessibility maintained
-- Best for history pages, heritage content
-
-**4. Balanced Approach**
-β **Green + Terracotta** (Palette C)
-
-- Combines tradition with warmth
-- References Richmond architecture
-- Best for general site-wide use
-
-**5. Safe Default**
-β **Classic Green** (Palette A)
-
-- Current palette, familiar
-- Proven accessibility
-- Best for conservative approach
-
----
-
-## Testing Recommendations
-
-### Browser Testing
-
-- β
Chrome/Edge (Blink engine)
-- β
Firefox (Gecko engine)
-- β
Safari (WebKit engine)
-- β
Mobile Safari (iOS)
-- β
Chrome Mobile (Android)
-
-### Screen Reader Testing
-
-- β
NVDA (Windows)
-- β
JAWS (Windows)
-- β
VoiceOver (macOS/iOS)
-- β
TalkBack (Android)
-
-### Vision Simulation
-
-Test each palette under:
-
-- **Protanopia** (red-blind)
-- **Deuteranopia** (green-blind)
-- **Tritanopia** (blue-blind)
-- **Achromatopsia** (monochrome)
-- **Low contrast** simulation
-
----
-
-## Implementation Notes
-
-### CSS Custom Properties
-
-All palettes use semantic color variables:
-
-```css
---color-primary-{50-950} /* Main brand color */
---color-accent-{50-950} /* Secondary accent color */
-```
-
-### Palette Switching
-
-Users can switch palettes via:
-
-- Mobile menu: Palette Switcher button
-- Color Playground: `/color-playground` route
-- Persists to `localStorage`
-- No flash on page load
-
-### Dark Mode
-
-- Automatic dark mode support for all palettes
-- Respects `prefers-color-scheme`
-- Manual toggle available
-- Independent from palette selection
-
----
-
-## Future Enhancements
-
-### Potential Additions
-
-1. **Seasonal Palettes:** Spring/Summer/Fall/Winter variations
-2. **Event-Specific:** Special palettes for major park events
-3. **High Contrast Mode:** Ultra-high contrast option for low vision
-4. **Reduced Motion:** Respect `prefers-reduced-motion`
-
-### A11y Features to Add
-
-- [ ] Focus visible outlines (2px solid)
-- [ ] Skip navigation links
-- [ ] ARIA landmarks throughout
-- [ ] Keyboard navigation indicators
-- [ ] Focus trap in modals
-
----
-
-## Compliance Statement
-
-**This website aims to conform to WCAG 2.1 Level AA standards.**
-
-All color palettes have been designed and tested to meet or exceed:
-
-- β
**WCAG 2.1 Level AA** for all essential content
-- β
**WCAG 2.1 Level AAA** for most body text combinations
-- β
**Section 508** compliance (U.S. federal standard)
-
-For accessibility issues or questions, please contact: [accessibility@chimboparkconservancy.org]
-
----
-
-## Audit Methodology
-
-### Tools Used
-
-- Manual calculation using WCAG 2.1 formulas
-- OKLCH color space for perceptual uniformity
-- Custom contrast calculation utilities (`src/utils/contrast.ts`)
-- Visual testing across multiple devices and browsers
-
-### Standards Referenced
-
-- [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/)
-- [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/)
-- [Accessible Colors](https://accessible-colors.com/)
-
----
-
-**Last Updated:** 2025-01-13
-**Next Review:** Quarterly or upon major design changes
-**Auditor:** Claude Code AI Assistant
diff --git a/COLOR_PALETTE_GUIDE.md b/COLOR_PALETTE_GUIDE.md
deleted file mode 100644
index 71d11a6..0000000
--- a/COLOR_PALETTE_GUIDE.md
+++ /dev/null
@@ -1,431 +0,0 @@
-# Color Palette Exploration Guide
-
-Welcome! This guide will help you explore and select the perfect color palette for the Chimborazo Park Conservancy website.
-
-## Quick Start
-
-### Testing the Palettes
-
-1. **Start the development server** (if not already running):
-
- ```bash
- npm run dev
- ```
-
-2. **Visit the Color Playground**:
- Open your browser to: `http://localhost:3001/color-playground`
-
-3. **Switch between palettes**:
- - Click the **"Palette"** button in the top section
- - Select any of the 6 available palettes
- - Changes apply instantly across the entire page
-
-4. **Toggle dark mode**:
- - Use the **"Theme"** button to test light/dark modes
- - All palettes support both modes
- - Your preference is saved automatically
-
----
-
-## Available Palettes
-
-### π² Classic Green (Default)
-
-**Best for:** Traditional, professional feel
-**Character:** Cool-toned forest green, nature-focused
-**Mood:** Established, trustworthy, natural
-
-**When to use:**
-
-- You prefer the current design
-- Want a safe, proven option
-- Need maximum professionalism
-
----
-
-### πΏ Warm Olive
-
-**Best for:** Approachable, organic feel
-**Character:** Warmer olive-toned greens
-**Mood:** Welcoming, earthy, friendly
-
-**When to use:**
-
-- Want more warmth than Classic Green
-- Prefer a softer, more inviting look
-- Value approachability over formality
-
----
-
-### ποΈ Green + Terracotta
-
-**Best for:** Historical warmth, Richmond heritage
-**Character:** Forest green + warm clay accents
-**Mood:** Historic, warm, rooted in place
-
-**When to use:**
-
-- Want to reference Richmond's brick architecture
-- Need both tradition AND warmth
-- Love the historical character of Church Hill
-- Want secondary color for variety
-
-**Why it's special:** The terracotta accent beautifully references Richmond's historic brick buildings and adds visual interest without being overwhelming.
-
----
-
-### π Green + Navy
-
-**Best for:** Institutional, trustworthy feel
-**Character:** Forest green + deep navy accents
-**Mood:** Professional, established, reliable
-
-**When to use:**
-
-- Need maximum trustworthiness
-- Working on grant applications or formal docs
-- Want the highest contrast (best accessibility)
-- Prefer a more conservative palette
-
-**Accessibility Note:** This palette has the highest contrast ratios of all options!
-
----
-
-### π― Sage + Amber
-
-**Best for:** Community warmth, volunteer engagement
-**Character:** Soft sage + warm honey tones
-**Mood:** Welcoming, cozy, community-focused
-
-**When to use:**
-
-- Community events are your primary focus
-- Recruiting volunteers
-- Want maximum approachability
-- Love warm, inviting colors
-
-**Perfect for:** Volunteer recruitment pages, community event announcements, neighborhood outreach
-
----
-
-### ποΈ Heritage (Iron + Brick)
-
-**Best for:** Historical authenticity, Victorian aesthetic
-**Character:** Iron green + brick red
-**Mood:** Historic, timeless, authentic
-
-**When to use:**
-
-- Want to emphasize the park's history
-- Love Victorian-era park aesthetics
-- Have historical content to showcase
-- Value authenticity and tradition
-
-**Historical Note:**
-
-- **Iron Green** = Traditional park ironwork and patina
-- **Brick Red** = Richmond's historic architecture
-
----
-
-## How to Test Palettes
-
-### 1. Color Playground (`/color-playground`)
-
-The playground shows:
-
-- All button styles
-- Card designs
-- Typography samples
-- Color swatches
-- Interactive form elements
-- Dark mode comparisons
-
-**Tip:** Try each palette in both light and dark modes!
-
----
-
-### 2. Real Content Pages
-
-Test palettes on actual pages:
-
-#### Homepage (`/`)
-
-- Hero section with image overlay
-- Vision cards
-- Event previews
-- Partner section
-
-#### Events Page (if available)
-
-- Event cards with status chips
-- Image overlays
-- Call-to-action buttons
-
-#### Media Page (`/media`)
-
-- Gallery layouts
-- Image treatments
-
-**How to test:**
-
-1. Navigate to any page
-2. Open mobile menu (hamburger icon)
-3. Scroll to bottom
-4. Click "Palette" button
-5. Select a palette
-6. Explore the page with new colors!
-
----
-
-### 3. Mobile Testing
-
-Don't forget to test on mobile!
-
-**Desktop:**
-
-- Open Chrome DevTools (F12)
-- Click "Toggle Device Toolbar" (Ctrl+Shift+M)
-- Select iPhone or Android device
-- Test palette switcher
-
-**Actual Mobile:**
-
-- Open on your phone
-- Test the mobile menu
-- Verify colors look good on your screen
-- Check dark mode (especially OLED screens)
-
----
-
-## Decision Framework
-
-### Ask Yourself These Questions:
-
-**1. What's our primary emotion?**
-
-- π― **Professional/Trustworthy** β Navy or Classic Green
-- π€ **Warm/Welcoming** β Sage+Amber or Green+Terra
-- π **Historic/Authentic** β Heritage
-- π± **Natural/Organic** β Olive or Classic Green
-
-**2. What's our main call-to-action?**
-
-- π° **Donations** β Navy (trust) or Classic (traditional)
-- π₯ **Volunteers** β Sage+Amber (community) or Green+Terra (warmth)
-- π **Education/History** β Heritage or Classic
-- π³ **General advocacy** β Olive or Classic
-
-**3. How do we want to stand out?**
-
-- π¨ **Unique/Memorable** β Heritage or Sage+Amber
-- π‘οΈ **Traditional/Safe** β Classic Green
-- π₯ **Warm/Inviting** β Green+Terra or Sage+Amber
-- πΌ **Professional** β Navy or Classic
-
-**4. What colors do we love?**
-
-- π **Just green** β Classic or Olive
-- π§‘ **Warm accents** β Green+Terra or Sage+Amber
-- π **Cool accents** β Green+Navy
-- β€οΈ **Historical** β Heritage (red accents)
-
----
-
-## Accessibility Guarantee
-
-β
**All palettes meet WCAG AA standards**
-β
**Most combinations achieve AAA level**
-β
**Dark mode fully supported**
-β
**Tested for color blindness**
-
-You can confidently choose based on aesthetics β accessibility is guaranteed!
-
-See `COLOR_PALETTE_AUDIT.md` for detailed contrast ratios.
-
----
-
-## Making the Switch
-
-### Once you've chosen a palette:
-
-#### For Development/Testing
-
-The palette preference is saved automatically to localStorage. Just select it and keep browsing!
-
-#### For Production
-
-To make a palette the site-wide default:
-
-**Option 1: Change Default (Code)**
-In `src/integrations/tanstack-query/root-provider.tsx`:
-
-```typescript
-// Change this line:
-this.currentPalette = getStoredPalette() || "green";
-
-// To your preferred palette:
-this.currentPalette = getStoredPalette() || "sage-amber"; // or any palette
-```
-
-**Option 2: Let Users Choose**
-Keep the palette switcher available so community members can choose their preference!
-
----
-
-## Seasonal Variations (Future Idea)
-
-Consider rotating palettes seasonally:
-
-- πΈ **Spring:** Sage + Amber (renewal, growth)
-- βοΈ **Summer:** Classic Green (lush, vibrant)
-- π **Fall:** Green + Terracotta (harvest, warmth)
-- βοΈ **Winter:** Green + Navy (evergreen, cold)
-
----
-
-## Feedback & Questions
-
-### What to consider when gathering feedback:
-
-**Test with actual users:**
-
-- Board members
-- Volunteers
-- Community members
-- Website visitors
-
-**Ask them:**
-
-1. Which palette feels most "Chimborazo Park"?
-2. Which makes you want to get involved?
-3. Which best represents our neighborhood?
-4. Do the colors work in both light and dark mode?
-
-**Get diverse perspectives:**
-
-- Different age groups
-- People with visual impairments
-- Smartphone vs. desktop users
-- Day vs. night mode users
-
----
-
-## Technical Details
-
-### Palette System Architecture
-
-**CSS Custom Properties:**
-
-```css
---color-primary-{50-950} /* Main brand color */
---color-accent-{50-950} /* Secondary color (if applicable) */
-```
-
-**Switching Mechanism:**
-
-- Palettes applied via `data-palette` attribute on ``
-- Default palette has no attribute
-- Changes via `setPalette()` function
-- Persists to localStorage
-- Syncs across browser tabs
-
-**Files:**
-
-- Palette definitions: `src/styles.css`
-- Palette utilities: `src/utils/palette.ts`
-- Hook: `src/hooks/usePalette.ts`
-- Switcher component: `src/components/PaletteSwitcher/`
-- Demo page: `src/routes/color-playground.tsx`
-
----
-
-## Quick Comparison Chart
-
-| Palette | Warmth | Professional | Historic | Unique | Complexity |
-| ------------- | ------ | ------------ | -------- | ------ | ----------- |
-| Classic Green | βββββ | βββββ | βββββ | βββββ | β Simple |
-| Warm Olive | βββββ | βββββ | βββββ | βββββ | β Simple |
-| Green+Terra | βββββ | βββββ | βββββ | βββββ | ββ Medium |
-| Green+Navy | βββββ | βββββ | βββββ | βββββ | ββ Medium |
-| Sage+Amber | βββββ | βββββ | βββββ | βββββ | ββ Medium |
-| Heritage | βββββ | βββββ | βββββ | βββββ | βββ Complex |
-
-**Legend:**
-
-- βββββ = Excellent
-- βββββ = Very Good
-- βββββ = Good
-- βββββ = Moderate
-- βββββ = Minimal
-
----
-
-## Recommended Workflow
-
-### Step-by-Step Palette Selection
-
-**Week 1: Initial Exploration**
-
-1. Visit `/color-playground`
-2. Try each palette in light mode
-3. Try each palette in dark mode
-4. Note your top 3 favorites
-
-**Week 2: Real Content Testing**
-
-1. Test your top 3 on the homepage
-2. Test on other key pages
-3. Test on mobile devices
-4. Get feedback from 2-3 people
-
-**Week 3: Decision Time**
-
-1. Narrow to top 2 palettes
-2. Present to board/key stakeholders
-3. Gather final feedback
-4. Make the decision!
-
-**Week 4: Implementation**
-
-1. Set chosen palette as default
-2. Optional: Keep switcher for user choice
-3. Update any marketing materials
-4. Announce the new look!
-
----
-
-## Still Can't Decide?
-
-### Try This:
-
-**Default Recommendation:** **Green + Terracotta** (Palette C)
-
-**Why?**
-
-- β
Maintains familiar green
-- β
Adds warmth via terracotta
-- β
References Richmond's heritage
-- β
Works for all content types
-- β
Balanced professionalism + approachability
-- β
Visually distinct from other organizations
-
-**Runner Up:** **Sage + Amber** (Palette E)
-
-- If community warmth is your #1 priority
-
----
-
-## Need Help?
-
-The palette system is fully implemented and ready to use. If you need assistance:
-
-1. Check `/color-playground` for live examples
-2. Review `COLOR_PALETTE_AUDIT.md` for technical details
-3. Test on real pages to see in context
-
-**Remember:** All palettes are accessible and professionally designed. You truly can't make a bad choice β it's about what feels most "Chimborazo Park" to you and your community! π³
-
----
-
-**Happy palette exploring!** π¨
diff --git a/COLOR_PALETTE_SUMMARY.md b/COLOR_PALETTE_SUMMARY.md
deleted file mode 100644
index 7f1dad4..0000000
--- a/COLOR_PALETTE_SUMMARY.md
+++ /dev/null
@@ -1,377 +0,0 @@
-# Color Palette Exploration - Implementation Summary
-
-## π What's Been Implemented
-
-You now have a complete color exploration system with **6 professional color palettes** designed specifically for the Chimborazo Park Conservancy website.
-
----
-
-## β¨ Features Delivered
-
-### 1. **Six Color Palettes**
-
-Each palette designed with warmth, community, and history in mind:
-
-1. **Classic Green** - Your current cool-toned forest green (baseline)
-2. **Warm Olive** - Warmer, more approachable olive tones
-3. **Green + Terracotta** - Forest green with warm clay accents (Richmond heritage)
-4. **Green + Navy** - Forest green with deep navy (professional, highest contrast)
-5. **Sage + Amber** - Soft sage with warm honey tones (maximum warmth)
-6. **Heritage** - Victorian iron green with brick red (historical authenticity)
-
-### 2. **Interactive Palette Switcher**
-
-- Accessible from mobile menu
-- Dropdown with all 6 options
-- Instant preview
-- Saves preference to localStorage
-- Syncs across browser tabs
-
-### 3. **Color Playground Page**
-
-Visit `/color-playground` to see:
-
-- Live component previews
-- Button styles in all variants
-- Card designs
-- Typography samples
-- Color swatches
-- Interactive form elements
-- Design principles
-- Dark mode comparisons
-
-### 4. **Full Dark Mode Support**
-
-- All 6 palettes work in dark mode
-- Maintained accessibility in both modes
-- Independent from palette selection
-- Respects system preferences
-
-### 5. **Accessibility Guaranteed**
-
-- β
All palettes meet WCAG AA standards
-- β
Most achieve AAA compliance
-- β
Contrast ratios documented
-- β
Tested for color blindness considerations
-- β
Screen reader compatible
-
----
-
-## π How to Use It Right Now
-
-### Quick Test:
-
-1. **Server is running** at `http://localhost:3001`
-2. Open mobile menu (hamburger icon)
-3. Scroll to bottom and click **"Palette"** button
-4. Select any palette β changes apply instantly!
-5. Try the **"Theme"** button to toggle dark mode
-6. Visit **`/color-playground`** for comprehensive preview
-
-### Visit These Pages:
-
-- **Homepage** (`/`) - See hero, cards, events
-- **Color Playground** (`/color-playground`) - Full component library
-- **Media** (`/media`) - Gallery with new colors
-- **Any page** - All pages support all palettes!
-
----
-
-## π Palette Recommendations
-
-### By Priority:
-
-**If you want maximum warmth & community feel:**
-β **Sage + Amber** or **Green + Terracotta**
-
-**If you want historical authenticity:**
-β **Heritage (Iron + Brick)**
-
-**If you want to stay close to current but warmer:**
-β **Warm Olive**
-
-**If you want maximum professionalism & trust:**
-β **Green + Navy**
-
-**If you want to play it safe:**
-β **Classic Green** (current)
-
-### My Top Recommendation:
-
-**Green + Terracotta** strikes the best balance:
-
-- Keeps familiar green
-- Adds warmth without being overwhelming
-- References Richmond's brick heritage
-- Works for all content types
-- Visually distinctive
-
----
-
-## π Files Created/Modified
-
-### New Files:
-
-- `src/utils/palette.ts` - Palette management utilities
-- `src/utils/contrast.ts` - WCAG contrast calculation
-- `src/hooks/usePalette.ts` - React hook for palette state
-- `src/components/PaletteSwitcher/palette-switcher.tsx` - Switcher component
-- `src/routes/color-playground.tsx` - Demo page
-- `COLOR_PALETTE_GUIDE.md` - User-friendly guide
-- `COLOR_PALETTE_AUDIT.md` - Accessibility documentation
-- `COLOR_PALETTE_SUMMARY.md` - This file!
-
-### Modified Files:
-
-- `src/styles.css` - Added all palette variations with CSS custom properties
-- `src/integrations/tanstack-query/root-provider.tsx` - Added palette state management
-- `src/routes/__root.tsx` - Added palette context type and initialization
-- `src/components/Header/header.tsx` - Added palette switcher to mobile menu
-
----
-
-## π¨ Technical Implementation
-
-### Color System Architecture:
-
-```
-CSS Custom Properties (Semantic)
- β
---color-primary-{shade} (maps to selected palette)
---color-accent-{shade} (maps to accent color if applicable)
- β
-Applied via data-palette attribute on
- β
-Managed by PaletteStateManager
- β
-Accessible via usePalette() hook
-```
-
-### How Switching Works:
-
-1. User selects palette from PaletteSwitcher
-2. `setPalette()` called via context
-3. Saved to localStorage (`palette-preference`)
-4. `data-palette` attribute updated on ``
-5. CSS custom properties remap to new colors
-6. All components update instantly (no refresh needed!)
-
-### Palette Loading:
-
-- Palette preference loaded before first paint (no flash!)
-- Blocking script in `` applies palette immediately
-- Falls back to "green" (current) if no preference saved
-
----
-
-## π― What You Can Do Next
-
-### Short Term (This Week):
-
-1. β
**Browse the color playground** - Get familiar with all options
-2. β
**Test on mobile** - See how colors look on phone/tablet
-3. β
**Try dark mode** - Test each palette in both modes
-4. β
**Pick your top 3** - Narrow down favorites
-
-### Medium Term (Next Week):
-
-1. **Get feedback** - Show board members, volunteers, community
-2. **Test with real content** - Add some text/images and see how it feels
-3. **Consider use cases** - Different palettes for different seasons/events?
-4. **Make a decision** - Choose your favorite!
-
-### Long Term (Optional):
-
-1. **Set as default** - Make your chosen palette the site default
-2. **Keep switcher** - Or let users choose their own preference
-3. **Seasonal rotation** - Switch palettes for seasons/special events
-4. **Brand guidelines** - Update any brand docs with new palette
-
----
-
-## π Documentation Quick Links
-
-**For Users (Non-Technical):**
-
-- Read `COLOR_PALETTE_GUIDE.md` for decision-making help
-- Compare palettes visually at `/color-playground`
-- Use the decision framework to narrow choices
-
-**For Developers (Technical):**
-
-- Read `COLOR_PALETTE_AUDIT.md` for contrast ratios and technical specs
-- Check `src/utils/palette.ts` for palette utilities
-- Review `src/styles.css` for OKLCH color definitions
-
----
-
-## π Quality Assurance
-
-### Testing Completed:
-
-- β
All 6 palettes implemented
-- β
Dark mode support for each palette
-- β
Contrast ratios calculated and documented
-- β
Component library built
-- β
Palette switcher functional
-- β
localStorage persistence
-- β
No-flash loading
-- β
Cross-browser compatibility (via CSS custom properties)
-- β
Mobile responsive
-
-### Accessibility Verified:
-
-- β
WCAG AA compliance (all palettes)
-- β
AAA compliance (most combinations)
-- β
Color-blind safe (tested with simulations)
-- β
Screen reader compatible
-- β
Keyboard navigable
-
----
-
-## π‘ Pro Tips
-
-### Getting the Most Out of Your Palettes:
-
-1. **Don't rush the decision** - Live with each palette for a day or two
-2. **Test with real content** - Colors look different with actual photos/text
-3. **Get diverse opinions** - Different ages, vision abilities, devices
-4. **Consider your audience** - What colors resonate with your community?
-5. **Think about seasons** - Some palettes work better in different seasons
-6. **Trust your instincts** - You know your community best!
-
-### If You're Stuck:
-
-- Start with **Green + Terracotta** - It's a solid middle ground
-- Get feedback from 5 community members - See which they prefer
-- Test on a staging site first - Before going live
-- Remember: You can always change it later!
-
----
-
-## π¨ Color Philosophy
-
-### Design Principles Applied:
-
-**1. Warmth & Community**
-All palettes designed to feel welcoming and approachable. Even the "professional" palettes maintain warmth.
-
-**2. Historical Connection**
-Colors reference Richmond's heritage:
-
-- Brick architecture (terracotta, brick red)
-- Victorian parks (iron green)
-- Natural landscape (greens, earth tones)
-
-**3. Accessibility First**
-Never sacrificed readability for aesthetics. All combinations meet high standards.
-
-**4. Flexibility**
-Six options ensure you can find the perfect fit for any content or season.
-
-**5. Modern Technology**
-OKLCH color space provides perceptually uniform colors that look great on all screens.
-
----
-
-## π Success Metrics
-
-### How to Measure Success:
-
-**Engagement:**
-
-- Do people spend more time on the site?
-- Does the palette make them want to get involved?
-
-**Accessibility:**
-
-- Can everyone read the content comfortably?
-- Does it work well in different lighting conditions?
-
-**Brand Alignment:**
-
-- Does it feel like "Chimborazo Park"?
-- Does it represent your community?
-
-**Distinctiveness:**
-
-- Does it stand out from other park websites?
-- Is it memorable?
-
----
-
-## π Next Steps
-
-### Immediate (Today):
-
-1. Visit `http://localhost:3001/color-playground`
-2. Try all 6 palettes
-3. Test in both light and dark modes
-4. Take screenshots of your favorites
-
-### This Week:
-
-1. Share `/color-playground` link with stakeholders
-2. Gather initial feedback
-3. Narrow to top 2-3 palettes
-4. Test on mobile devices
-
-### Next Week:
-
-1. Final decision on palette
-2. Optional: Set as default in code
-3. Optional: Keep switcher for user choice
-4. Celebrate your new look! π
-
----
-
-## β Common Questions
-
-**Q: Can I use different palettes on different pages?**
-A: Currently, the palette is site-wide. But you could implement page-specific overrides if needed.
-
-**Q: Will this affect my existing styles?**
-A: No! All existing code still works. The semantic color system maps to existing usage.
-
-**Q: Can users save their preference?**
-A: Yes! Palette choice is automatically saved to localStorage and persists across visits.
-
-**Q: What if I want to change the colors in a palette?**
-A: Edit the OKLCH values in `src/styles.css` under the appropriate palette definition.
-
-**Q: Can I create a 7th palette?**
-A: Absolutely! Follow the pattern in `src/styles.css` and add it to the PALETTE_METADATA in `src/utils/palette.ts`.
-
-**Q: Do I need to keep the switcher on the site?**
-A: Nope! Once you choose a default palette, you can remove the PaletteSwitcher component from the Header if you want a consistent look for all visitors.
-
----
-
-## π Acknowledgments
-
-This color exploration system was designed with careful attention to:
-
-- Richmond's historic character
-- Chimborazo Park's natural beauty
-- Your community's needs
-- Modern accessibility standards
-- Professional design principles
-
-**The result:** Six beautiful, accessible, meaningful palettes that honor your park's past while looking toward its future.
-
----
-
-## π Conclusion
-
-You now have a powerful color exploration system that lets you test multiple professional palettes in real-time. Every palette has been crafted to evoke warmth, community, and history while maintaining excellent accessibility.
-
-**Take your time**, test thoroughly, gather feedback from your community, and choose the palette that feels most "Chimborazo Park" to you.
-
-The playground is ready to explore! π¨π³
-
----
-
-**Questions or need help deciding?**
-All the documentation and tools you need are in place. Trust the process, involve your community, and enjoy discovering your perfect palette!
-
-**Happy exploring!** π¨β¨
diff --git a/GEMINI.md b/GEMINI.md
new file mode 100644
index 0000000..e69de29
diff --git a/NETLIFY_BLOBS_SETUP.md b/NETLIFY_BLOBS_SETUP.md
deleted file mode 100644
index 6e23514..0000000
--- a/NETLIFY_BLOBS_SETUP.md
+++ /dev/null
@@ -1,288 +0,0 @@
-# Netlify Blobs Media Storage Setup
-
-This document explains how to use Netlify Blobs for storing and managing images in the media gallery.
-
-## Overview
-
-The media page now uses Netlify Blobs to store images instead of keeping them in the codebase. This provides several benefits:
-
-- **Scalability**: Store unlimited images without bloating the git repository
-- **Performance**: Images are served with optimal caching headers
-- **Metadata**: Each image includes alt text, captions, and dimensions
-- **Easy Management**: Upload new images without redeploying the site
-
-## Architecture
-
-### Components
-
-1. **Data Type** (`src/data/media.ts`): TypeScript interface defining image metadata structure
-2. **Netlify Functions**:
- - `functions/get-media.ts`: Fetches all media with metadata from blob storage
- - `functions/upload-media.ts`: Uploads images with metadata (admin only, requires auth)
-3. **Netlify Edge Functions**:
- - `edge-functions/media-image.ts`: Serves individual images from blob storage via global edge network
-4. **Media Page** (`src/routes/media.tsx`): Displays images in masonry layout with hover captions
-5. **Migration Script** (`scripts/migrate-images.ts`): One-time migration of existing images to blob storage
-
-## Setup Instructions
-
-### 1. Environment Variables
-
-Create a `.env` file in the project root (copy from `.env.example`):
-
-```bash
-# Required for Netlify Blobs
-NETLIFY_SITE_ID=your-site-id-here
-
-# Required for running migration script locally
-NETLIFY_TOKEN=your-netlify-token-here
-
-# Required for upload function (generate a secure random string)
-ADMIN_API_KEY=your-secure-admin-key-here
-```
-
-**To find your Site ID:**
-
-1. Go to your Netlify dashboard at https://app.netlify.com
-2. Select your site
-3. Navigate to Site settings > General > Project information
-4. Copy the "Site ID"
-
-**To get your Personal Access Token:**
-
-1. Go to https://app.netlify.com/user/applications#personal-access-tokens
-2. Click "New access token"
-3. Give it a name like "Blobs Migration"
-4. Copy the token and add it to your `.env` file
-5. β οΈ **Keep this secret!** Never commit it to git
-
-**For the Admin API Key:**
-
-- Generate a secure random string (e.g., using `openssl rand -base64 32`)
-- This is used for the upload function to prevent unauthorized uploads
-
-### 2. Migrate Existing Images
-
-Run the migration script to upload your existing images from the `/public` directory:
-
-```bash
-npx tsx scripts/migrate-images.ts
-```
-
-This will:
-
-- Read all `.webp` images from the `public/` directory
-- Extract dimensions using `sharp`
-- Upload to Netlify Blobs with metadata (alt text, captions, dimensions)
-- Skip images that already exist in blob storage
-
-### 3. Deploy to Netlify
-
-The functions will automatically work on Netlify. Make sure to set the environment variables in your Netlify dashboard:
-
-1. Go to Site settings > Environment variables
-2. Add `ADMIN_API_KEY` with a secure value
-
-Note: `NETLIFY_SITE_ID` is automatically available in Netlify's environment.
-
-## Usage
-
-### Viewing Images
-
-Simply visit `/media` on your site. Images will load from Netlify Blobs with:
-
-- Responsive masonry layout (1-3 columns based on screen size)
-- Captions appear on hover
-- Proper alt text for accessibility
-- Optimized caching
-
-### Uploading New Images
-
-To upload a new image, send a POST request to `/.netlify/functions/upload-media`:
-
-```bash
-curl -X POST https://your-site.netlify.app/.netlify/functions/upload-media \
- -H "Authorization: Bearer YOUR_ADMIN_API_KEY" \
- -F "image=@path/to/image.webp" \
- -F "key=unique-image-key.webp" \
- -F "alt=Description of the image" \
- -F "caption=Optional caption text" \
- -F "width=1600" \
- -F "height=900"
-```
-
-Required fields:
-
-- `image`: The image file
-- `key`: Unique identifier (usually the filename)
-- `alt`: Alt text for accessibility
-- `width`: Image width in pixels
-- `height`: Image height in pixels
-
-Optional fields:
-
-- `caption`: Caption displayed on hover
-
-### Image Metadata Structure
-
-Each image stored in Netlify Blobs includes:
-
-```typescript
-{
- key: string; // Unique identifier (filename)
- src: string; // URL to fetch the image
- width: number; // Image width in pixels
- height: number; // Image height in pixels
- alt: string; // Alt text for accessibility
- caption?: string; // Optional caption
- uploadedAt: string; // ISO timestamp
-}
-```
-
-## Development
-
-### Local Testing
-
-The Netlify CLI automatically emulates Blobs in local development. Just run:
-
-```bash
-npm run dev
-```
-
-Images uploaded in development are stored locally and won't persist to production.
-
-### Adding New Images Locally
-
-1. Place your image in the `public/` directory
-2. Add metadata to `scripts/migrate-images.ts` in the `imageMetadata` object
-3. Run the migration script: `npx tsx scripts/migrate-images.ts`
-
-## Performance & Caching Strategy
-
-### Edge Function Architecture
-
-Images are served via **Netlify Edge Functions** running on Deno Deploy's global network:
-
-- β
**Low latency worldwide** - Functions execute close to users
-- β
**No cold starts** - Edge Functions are always warm
-- β
**Optimized for reads** - Perfect for frequently-accessed media
-- β
**Strong consistency** - Ensures new uploads are immediately available
-
-### Caching Headers
-
-**Images** (Edge Function at `/media-img/{key}`):
-
-```
-Cache-Control: public, max-age=31536000, immutable
-CDN-Cache-Control: public, max-age=31536000, immutable
-```
-
-- **1 year browser cache** - After first load, served from local cache (no network!)
-- **1 year CDN cache** - Netlify CDN caches at the edge globally
-- **immutable** - Browser knows file never changes (optimizes refresh behavior)
-
-**Media List** (Function at `/.netlify/functions/get-media`):
-
-```
-Cache-Control: public, max-age=300, s-maxage=600
-```
-
-- **5 minutes client cache** - Reduces API calls
-- **10 minutes CDN cache** - Faster list retrieval, balances freshness
-- New images appear within 10 minutes without redeployment
-
-### Performance Characteristics
-
-**First Load:**
-
-1. Client requests `/media`
-2. Loader fetches list from `get-media` (~50-200ms)
-3. Browser loads images from edge function (~20-100ms per image)
-4. Subsequent images load in parallel
-
-**Subsequent Loads:**
-
-1. List served from browser/CDN cache (~0-10ms)
-2. Images served from browser cache (~0ms, no network request!)
-
-**Upload New Image:**
-
-1. Upload via `upload-media` with strong consistency
-2. Appears in feed within 10 minutes (CDN cache expiry)
-3. First load ~20-100ms, then cached for 1 year
-
-### Why This is Fast
-
-1. **Edge Functions** - Images served from 300+ edge locations worldwide
-2. **Aggressive caching** - After first page load, images load instantly from cache
-3. **Parallel loading** - Browser loads multiple images simultaneously
-4. **Immutable content** - Browsers can optimize caching behavior
-5. **CDN integration** - Netlify's CDN caches at multiple layers
-
-### Comparison to Traditional Approaches
-
-| Approach | First Load | Cached Load | Global Performance |
-| ------------------------- | ------------- | ----------- | -------------------------- |
-| Git + Public folder | ~50-200ms | ~0-10ms | Varies by CDN |
-| Regular Functions | ~200-500ms | ~0-10ms | Single region bottleneck |
-| **Edge Functions (ours)** | **~20-100ms** | **~0ms** | **Globally optimized** |
-| AWS S3 + CloudFront | ~50-150ms | ~0-10ms | Excellent (but more setup) |
-
-### Expected Performance Metrics
-
-For a typical gallery visit:
-
-- **Initial page load**: 0.5-2 seconds (depending on # of images)
-- **Return visit**: <100ms (everything cached)
-- **New image upload**: Available within 10 minutes
-- **Image loading**: Waterfall completes in 1-3 seconds for 20-30 images
-
-### Monitoring Performance
-
-Check your site's performance in:
-
-1. Netlify Analytics - Real user monitoring
-2. Browser DevTools Network tab - See cache hits
-3. Lighthouse - Should score 90+ for performance
-
-## Troubleshooting
-
-### Images Not Loading
-
-1. Check that `NETLIFY_SITE_ID` is set correctly
-2. Verify the migration script ran successfully
-3. Check the browser console for errors
-4. Ensure Netlify Blobs is enabled for your plan
-
-### Upload Fails
-
-1. Verify `ADMIN_API_KEY` is set in environment
-2. Check image file size (Netlify Blobs has size limits per plan)
-3. Ensure all required fields are provided
-
-### Local Development Issues
-
-1. Make sure you're using Netlify Dev: `npm run dev`
-2. Check that `.netlify` directory exists (auto-created)
-3. Restart the dev server if blob storage seems stuck
-
-## Future Enhancements
-
-Potential improvements you could add:
-
-- [ ] Admin UI for uploading images through the browser
-- [ ] Image resizing/optimization in upload function
-- [ ] Pagination for large galleries
-- [ ] Image categories/tags
-- [ ] Lightbox for full-size viewing
-- [ ] Delete functionality
-- [ ] Bulk upload support
-
-## Cost Considerations
-
-Netlify Blobs pricing (as of 2025):
-
-- **Free tier**: Included in free plan with limits
-- **Pro tier**: Higher limits, check Netlify pricing page
-
-Monitor your usage in the Netlify dashboard under Blobs section.
diff --git a/PERFORMANCE_IMPROVEMENTS.md b/PERFORMANCE_IMPROVEMENTS.md
deleted file mode 100644
index 1fc4561..0000000
--- a/PERFORMANCE_IMPROVEMENTS.md
+++ /dev/null
@@ -1,443 +0,0 @@
-# Performance Improvement Recommendations
-
-Based on Lighthouse audit results from October 15, 2025
-
-## Current Performance Score: 85/100
-
-### Core Web Vitals Summary
-
-| Metric | Score | Value | Status |
-| ---------------------------------- | ----- | ----- | ------------------------ |
-| **First Contentful Paint (FCP)** | 0.98 | 0.7s | β
Excellent |
-| **Largest Contentful Paint (LCP)** | 0.88 | 1.3s | β
Good |
-| **Total Blocking Time (TBT)** | 1.0 | 0ms | β
Perfect |
-| **Cumulative Layout Shift (CLS)** | 0.55 | 0.225 | β οΈ **Needs Improvement** |
-| **Speed Index** | 0.98 | 0.9s | β
Excellent |
-
----
-
-## Priority 1: Fix Cumulative Layout Shift (CLS) - 0.225 β οΈ
-
-**Impact:** Highest priority - accounts for 25% of performance score
-
-### Problem
-
-Layout shifts occur when images and other content load without reserved space, causing visual instability.
-
-### Solutions
-
-#### 1. Add Explicit Dimensions to Images
-
-```typescript
-// Bad - no dimensions specified
-
-
-// Good - explicit dimensions
-
-```
-
-#### 2. Use CSS Aspect Ratio
-
-```css
-.hero-image {
- aspect-ratio: 16 / 9;
- width: 100%;
-}
-
-.event-thumbnail {
- aspect-ratio: 4 / 3;
- width: 100%;
-}
-```
-
-#### 3. Reserve Space for Dynamic Content
-
-```typescript
-// For TanStack Devtools or other dynamic UI
-.devtools-container {
- min-height: 56px; /* Reserve space before load */
-}
-```
-
-#### 4. Optimize Font Loading (Prevents FOIT/FOUT)
-
-See "Priority 3" below for font optimization details.
-
-### Expected Improvement
-
-**+10-15 points** to performance score
-
----
-
-## Priority 2: Implement Responsive Images πΌοΈ
-
-**Impact:** Est. savings of 327 KiB
-
-### Problem
-
-Images are served at larger sizes than needed for the viewport:
-
-- `festival.webp` - 146 KB wasted
-- `recreation.webp` - 103 KB wasted
-- `get_involved.webp` - 85 KB wasted
-
-### Solution 1: Use @unpic/react (Already in dependencies!)
-
-```typescript
-import { Image } from '@unpic/react';
-
-
-```
-
-### Solution 2: Native Picture Element
-
-```tsx
-
-
-
-
-```
-
-### Solution 3: Generate Multiple Image Sizes
-
-Add a build step to generate responsive images:
-
-```bash
-npm install -D sharp
-```
-
-Create a script `scripts/generate-images.js`:
-
-```javascript
-import sharp from "sharp";
-import { readdir } from "fs/promises";
-import path from "path";
-
-const sizes = [640, 768, 1024, 1280, 1536];
-const inputDir = "./public";
-const images = ["festival.webp", "recreation.webp", "get_involved.webp"];
-
-for (const image of images) {
- const baseName = path.parse(image).name;
-
- for (const size of sizes) {
- await sharp(path.join(inputDir, image))
- .resize(size, null, { withoutEnlargement: true })
- .webp({ quality: 85 })
- .toFile(path.join(inputDir, `${baseName}-${size}.webp`));
- }
-}
-```
-
-Add to package.json:
-
-```json
-{
- "scripts": {
- "generate-images": "node scripts/generate-images.js",
- "prebuild": "npm run generate-images"
- }
-}
-```
-
-### Expected Improvement
-
-**+3-5 points** to performance score
-
----
-
-## Priority 3: Optimize Font Loading π€
-
-**Impact:** Est. savings of 386ms render blocking time
-
-### Current Problem
-
-Google Fonts CSS is blocking render.
-
-### Solution 1: Async Load External Fonts (Quick Fix)
-
-Update font loading in `src/routes/__root.tsx`:
-
-```html
-
-
-
-
-
-
-
-```
-
-### Solution 2: Self-Host Fonts (Best Practice)
-
-```bash
-npm install @fontsource/inter @fontsource/libre-baskerville @fontsource/montserrat @fontsource/vollkorn-sc
-```
-
-In `src/routes/__root.tsx` or `src/styles.css`:
-
-```typescript
-// Import only the weights you need
-import "@fontsource/inter/400.css";
-import "@fontsource/inter/700.css";
-import "@fontsource/libre-baskerville/400.css";
-import "@fontsource/libre-baskerville/700.css";
-import "@fontsource/montserrat/400.css";
-import "@fontsource/montserrat/700.css";
-import "@fontsource/vollkorn-sc/400.css";
-import "@fontsource/vollkorn-sc/700.css";
-```
-
-Then update `src/styles.css` to use local fonts:
-
-```css
-/* Remove or comment out @import statements for Google Fonts */
-/* @import url('https://fonts.googleapis.com/...'); */
-
-/* Font families remain the same */
-:root {
- --font-display: "Vollkorn SC", serif;
- --font-body: "Inter", sans-serif;
-}
-```
-
-### Expected Improvement
-
-**+2-3 points** to performance score
-
----
-
-## Priority 4: Reduce Unused JavaScript π¦
-
-**Impact:** Est. savings of 422 KiB (75 KB from main bundle)
-
-### Problem
-
-Main application bundle contains ~75 KB of unused JavaScript code.
-
-### Solutions
-
-#### 1. Lazy Load Routes
-
-TanStack Router already supports code splitting. Use lazy loading for non-critical routes:
-
-```typescript
-// src/routes/media.tsx
-import { createFileRoute, lazyRouteComponent } from "@tanstack/react-router";
-
-export const Route = createFileRoute("/media")({
- component: lazyRouteComponent(() => import("../components/MediaGallery/media-gallery")),
-});
-```
-
-#### 2. Lazy Load Heavy Components
-
-```typescript
-import { lazy, Suspense } from 'react';
-
-// Lazy load non-critical components
-const EventCard = lazy(() => import('@/components/Event/event-card'));
-
-function EventList() {
- return (
- Loading... }>
-