# High Performance Structures Website

A modern, high-performance website for High Performance Structures - a Colorado-based company specializing in Insulating Concrete Form (ICF) construction services. Built with Next.js 16 and deployed to Cloudflare Workers for global edge distribution.

## 🚀 Tech Stack

- **Framework:** [Next.js 16](https://nextjs.org/) with App Router
- **UI Library:** [React 19](https://react.dev/)
- **Language:** [TypeScript](https://www.typescriptlang.org/)
- **Styling:** [Tailwind CSS v4](https://tailwindcss.com/) with CSS variables
- **Components:** [shadcn/ui](https://ui.shadcn.com/) (Radix UI primitives)
- **Deployment:** [Cloudflare Workers](https://developers.cloudflare.com/workers/)
- **Bridge:** [OpenNext Cloudflare](https://opennext.js.org/cloudflare)
- **Icons:** [Lucide React](https://lucide.dev/)
- **Forms:** [React Hook Form](https://react-hook-form.com/) + [Zod](https://zod.dev/)
- **Analytics:** [Vercel Web Analytics](https://vercel.com/analytics)

## ✨ Features

- **Responsive Design** - Mobile-first approach with optimized layouts for all screen sizes
- **Modern UI** - Clean, professional interface built with shadcn/ui components
- **Server-Side Rendering** - SSR/SSG capabilities for optimal performance and SEO
- **Edge Deployment** - Global distribution via Cloudflare's edge network
- **Blog System** - Dynamic blog post pages with markdown support
- **Contact Forms** - Validated contact forms with React Hook Form and Zod
- **Service Showcases** - Dedicated pages for ICF services, training, and resources
- **Performance Optimized** - Fast page loads with optimized images and static assets

## 📋 Prerequisites

- **Node.js** 18.x or higher
- **pnpm** (package manager) - Install with `npm install -g pnpm`
- **Cloudflare Account** (for deployment)

## 🛠️ Getting Started

### Installation

1. Clone the repository:
```bash
git clone <repository-url>
cd high-performance-structures
```

2. Install dependencies:
```bash
pnpm install
```

3. Start the development server:
```bash
pnpm dev
```

4. Open [http://localhost:3000](http://localhost:3000) in your browser.

The page will automatically reload when you make changes to the code.

## 📜 Available Scripts

### Development

```bash
pnpm dev          # Start Next.js dev server (http://localhost:3000)
pnpm lint         # Run ESLint code quality checks
```

### Build & Deployment

```bash
pnpm build        # Create production build (.next/ and .open-next/ outputs)
pnpm start        # Start production server locally
pnpm preview      # Test on Cloudflare Workers runtime locally
pnpm deploy       # Deploy to Cloudflare Workers (requires authentication)
```

### Component Management

```bash
npx shadcn-ui@latest add [component-name]  # Add shadcn/ui component
```

## 📁 Project Structure

```
high-performance-structures/
├── app/                    # Next.js App Router pages
│   ├── page.tsx           # Home page
│   ├── layout.tsx         # Root layout with metadata
│   ├── globals.css        # Global styles and Tailwind config
│   ├── blog/              # Blog pages
│   │   ├── page.tsx       # Blog listing
│   │   └── [slug]/        # Dynamic blog post pages
│   ├── services/          # Services page
│   ├── contact/           # Contact page
│   └── resources/         # Resources page
├── components/            # React components
│   ├── ui/               # shadcn/ui components (30+ components)
│   ├── site-header.tsx   # Site header with navigation
│   ├── site-footer.tsx   # Site footer
│   └── hps-logo.tsx      # Brand logo component
├── lib/                  # Utilities
│   └── utils.ts          # cn() function for merging Tailwind classes
├── hooks/                # Custom React hooks
│   ├── use-toast.ts      # Toast notifications
│   └── use-mobile.ts     # Mobile detection
├── public/               # Static assets
│   ├── images/          # Image assets
│   ├── logos/           # Logo files
│   └── _headers         # Cloudflare caching rules
├── next.config.ts        # Next.js configuration
├── wrangler.jsonc        # Cloudflare Workers configuration
├── open-next.config.ts   # OpenNext bridge configuration
├── tsconfig.json         # TypeScript configuration
└── package.json          # Dependencies and scripts
```

## 🏗️ Architecture

### High-Level Stack

```
React 19 Components
    ↓
Next.js 16 App Router (SSR/SSG)
    ↓
Cloudflare Workers (via OpenNext bridge)
    ↓
Cloudflare Edge Network (global distribution)
```

### Build Outputs

- **`.next/`** - Standard Next.js build output
- **`.open-next/`** - OpenNext bridge output for Cloudflare
  - `worker.js` - Cloudflare Worker entry point
  - `assets/` - Static files for edge serving

## ⚙️ Configuration

### TypeScript Path Aliases

The project uses path aliases for cleaner imports:

```json
{
  "paths": {
    "@/*": ["./*"]
  }
}
```

**Import pattern:** `import { Component } from "@/components/Component"`

### Tailwind CSS v4

The project uses **Tailwind CSS v4** with CSS-only configuration in `app/globals.css`:

```css
@import "tailwindcss";

:root {
  --primary-blue: #0066bf;
  --deep-navy: #0f172a;
  --cyan-accent: #8cc63f;
  /* ... more variables ... */
}
```

**Key Brand Colors:**
- Deep Navy: `#0f172a` - Primary background
- Primary Blue: `#0066bf` - Action elements
- Cyan/Lime Accent: `#8cc63f` - Brand highlight

Dark mode is supported via `next-themes` package.

### Component Library (shadcn/ui)

All UI components use **shadcn/ui** (Radix UI primitives + Tailwind):
- Location: `components/ui/`
- Style: New York (modern, clean)
- Icons: Lucide React
- Installation: `npx shadcn-ui@latest add [component]`
- Configuration: `components.json`

## 🔧 Development Workflows

### Adding a New Page

1. Create directory under `app/` (e.g., `app/new-page/`)
2. Add `page.tsx` file with default export component:
```typescript
export default function NewPage() {
  return <div>New Page Content</div>
}
```
3. Optionally create `layout.tsx` for page-specific layout
4. Import `SiteHeader` and `SiteFooter` for consistent layout

### Adding UI Components

```bash
npx shadcn-ui@latest add button
npx shadcn-ui@latest add card
npx shadcn-ui@latest add form
```

All components are composable and styled with Tailwind.

### Creating Forms

```typescript
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import { z } from "zod"

const schema = z.object({
  email: z.string().email("Invalid email"),
  message: z.string().min(10),
})

export default function MyForm() {
  const form = useForm({
    resolver: zodResolver(schema),
  })
  // form.register(), form.handleSubmit(), etc.
}
```

### Dark Mode Implementation

Uses `next-themes`:

```typescript
import { useTheme } from "next-themes"

const { theme, setTheme } = useTheme()
```

CSS dark mode via `prefers-color-scheme` media query + `.dark` class support.

## 🚢 Deployment

### Cloudflare Workers Configuration

**Wrangler Setup** (`wrangler.jsonc`):
- Worker entry: `.open-next/worker.js`
- Compatibility date: `2025-03-01`
- Node.js compatibility enabled: `nodejs_compat` flag
- Static assets binding: `ASSETS` → `.open-next/assets`
- Observability: Enabled

### Deployment Process

**Important:** Follow these steps in order:

1. **Build for Cloudflare:**
```bash
npx @opennextjs/cloudflare build
```

2. **Deploy to Cloudflare:**
```bash
npx wrangler deploy
```

**Note:** Do NOT skip the build step. Wrangler deploys without this step will push stale assets.

### Caching Strategy

**Static assets** (in `public/_headers`):
```
/_next/static/*
  Cache-Control: public,max-age=31536000,immutable
```

- Cached for 1 year at edge
- Content hash in filename ensures cache busting

### Account Management

Cloudflare account is stored in local Wrangler config (`~/.wrangler/config.json`). To switch accounts:

```bash
wrangler logout
wrangler login
```

### Local Preview

```bash
pnpm preview
```

Simulates Cloudflare Workers runtime locally using Wrangler.

## 🔐 Environment Variables

### Development

- **File:** `.dev.vars` (Git ignored)
- **Template:** `.dev.vars.example`
- **Content:** Currently just `NEXTJS_ENV=development`

Used by Wrangler for local development. Extend as needed for API keys, secrets, etc.

### Production

Set environment variables in Cloudflare Dashboard or via Wrangler:

```bash
wrangler secret put MY_SECRET
```

## 📚 Additional Resources

### Documentation

- [Next.js Documentation](https://nextjs.org/docs)
- [OpenNext Cloudflare](https://opennext.js.org/cloudflare)
- [Tailwind CSS v4](https://tailwindcss.com/docs)
- [shadcn/ui](https://ui.shadcn.com/)
- [Cloudflare Workers](https://developers.cloudflare.com/workers/)
- [React Hook Form](https://react-hook-form.com/)
- [Zod](https://zod.dev/)

### Related Tools

- [Radix UI](https://www.radix-ui.com/) - Unstyled, accessible component primitives
- [Lucide Icons](https://lucide.dev/) - Beautiful icon library
- [Vercel Analytics](https://vercel.com/analytics) - Web analytics

## 🐛 Troubleshooting

### Module not found errors for `@/lib/utils` or components

Ensure files exist in project root at correct paths and `tsconfig.json` path alias points to `"./*"`.

### OpenNext Cloudflare for Dev

The `initOpenNextCloudflareForDev()` call in `next.config.ts` enables `getCloudflareContext()` usage in `next dev` mode.

### React 19 Compatibility

- `vaul@^1.0.0` required (not 0.9.x which only supports React 18)
- All shadcn/ui components tested with React 19

### Build Errors

- **ESLint config errors during build:** They're informational—build still succeeds, but you should address them separately.
- **Viewport metadata warning:** Move viewport values from metadata to generateViewport per Next.js docs.

## 📝 License

Private project - All rights reserved.

## 👥 Contact

For questions about this project, please contact the development team.

---

Built with ❤️ using Next.js and Cloudflare Workers
