diff --git a/README.md b/README.md
index 04ee70586..638967a61 100644
--- a/README.md
+++ b/README.md
@@ -1,161 +1,981 @@
-# United Tattoo — Official Website (Next.js + ShadCN UI)
+
-# DEPLOYMENT COMMAND `npm run pages:build && wrangler deploy`
+
+
+
DEPLOYMENT COMMAND
+ npm run pages:build && wrangler deploy
+
-Hi, I’m Nicholai. I built this site for my friend Christy (aka Ink Mama) and the United Tattoo crew in Fountain, CO. The goal was simple: give the studio a site that actually reflects the art, the people, and the experience — not the stiff, generic stuff you usually see. This is also a thank you for everything Christy has done for Amari (my girlfriend and soulmate), who was her apprentice. So yeah, this is personal — and it shows.
+
-This repo powers the official United Tattoo website, built with:
-- Next.js App Router
-- TypeScript
-- Tailwind CSS
-- ShadCN UI components (used across all pages)
-- Lenis (smooth scroll)
-- Lucide (icons)
+
+[![Contributors][contributors-shield]][contributors-url]
+[![Issues][issues-shield]][issues-url]
-Live dev server: http://localhost:3000
+
+
+
-- app/
- - page.tsx — homepage (Hero, Artists, Services, Contact sections)
- - aftercare/page.tsx — aftercare instructions (ShadCN-driven)
- - deposit/page.tsx — deposit policy + payment options (Afterpay, Stripe)
- - terms/page.tsx — terms of service
- - privacy/page.tsx — privacy policy
- - artists/ — artists listing + dynamic routes for profiles (coming from data)
- - book/page.tsx — booking flow
- - specials/page.tsx — promotions (monthly specials, VIP list)
- - contact/page.tsx — contact
- - gift-cards/page.tsx — gift card info
+---
-- components/
- - hero-section.tsx, artists-section.tsx, services-section.tsx, contact-section.tsx
- - aftercare-page.tsx, deposit-page.tsx, terms-page.tsx, privacy-page.tsx
- - booking-form.tsx — multi-step form using ShadCN components
- - footer.tsx — contains direct links to Aftercare, Deposit Policy, Terms, and Privacy
- - ui/ — ShadCN UI primitives
+
+## Table of Contents
-- data/
- - artists.ts — single source of truth for artist metadata and images used across pages
+- [About The Project](#about-the-project)
+ - [Key Features](#key-features)
+- [Tech Stack](#tech-stack)
+- [Architecture](#architecture) [Getting Started](#getting-started) [Prerequisites](#prerequisites)
+ - [Installation](#installation)
+ - [Environment Variables](#environment-variables)
+- [Development](#development)
+ - [Common Commands](#common-commands)
+ - [Database Management](#database-management)
+- [Deployment](#deployment)
+- [Documentation](#documentation)
+- [Roadmap](#roadmap)
+- [Contributing](#contributing)
+- [License](#license)
+- [Contact](#contact)
-- public/
- - united-logo-*.png/jpg, artists/, and other stable assets
+---
+
-## Content & Assets
+## About The Project
-- All the “real” content, bios, and images are now wired in (not seed placeholders).
-- Artist portraits and tattoo samples live under public/artists/.
-- Pages like Aftercare, Deposit, Terms, and Privacy use consistent styling patterned after the homepage and portfolio pages — powered by ShadCN components.
+
+

+
-If you need to re-copy images from the temp folder into public (on your machine), there’s a helper script:
-- ./copy-artist-images.sh
-Note: This script expects the temp directory structure to exist locally; it silently skips if a source is missing.
+
+**United Tattoo** is an all-in-one tool built for [United Tattoo](https://united-tattoos.com), a tattoo studio in **Fountain, Colorado**. It brings together artist portfolios, appointment booking, a flash tattoo marketplace, and calendar sync, all running on Cloudflare for speed and reliability.
-## Getting Started (Local Dev)
+### Key Features
-- Install deps:
- - npm install
+- Artist portfolios with Instagram links
+- Simple artist pages and management
+- Book appointments online
+- Browse and book flash tattoo designs
+- Nextcloud sync for calendars and user login
+- Admin and artist dashboards
+- File and image uploads
-- Run dev server:
- - npm run dev
- - Open http://localhost:3000
+(back to top)
-- Lint (optional):
- - npm run lint
+---
-Build:
-- npm run build
-- npm start
+## Tech Stack
+
-## Continuous Integration (CI)
+### Core Framework
+[![Next.js][nextjs-badge]][next-url]
+[![React][react-badge]][react-url]
+[![TypeScript][typescript-badge]][typescript-url]
-This repo includes a CI workflow that enforces linting, type safety, unit tests, build/preview, and bundle size budgets.
+### Cloudflare Infrastructure
+[![Cloudflare Workers][cloudflare-badge]][cloudflare-url]
+[![OpenNext][opennext-badge]][opennext-url]
-- Workflow file: `.gitea/workflows/ci.yaml`
-- Triggers: Push and PR against `main`/`master`
-- Node: 20.x with `npm ci`
+### UI & Styling
+[![ShadCN UI][shadcn-badge]][shadcn-url]
+[![Tailwind CSS][tailwind-badge]][tailwind-url]
+[![Framer Motion][framer-badge]][framer-url]
-Stages
-- Lint: `npm run ci:lint` (ESLint)
-- Typecheck: `npm run ci:typecheck` (TypeScript noEmit)
-- Unit tests: `npm run ci:test` (Vitest with coverage)
-- Build: `npm run ci:build` (OpenNext build to `.vercel/output/static`)
-- Preview smoke: start OpenNext preview briefly to ensure no immediate crash
-- Budgets: `npm run ci:budgets` (analyzes `.vercel/output/static`)
+### Database & Storage
+[![Cloudflare D1][d1-badge]][d1-url]
+[![Cloudflare R2][r2-badge]][r2-url]
-Bundle Size Budgets
-- Defaults are defined in `package.json` under the `budgets` key:
- - `TOTAL_STATIC_MAX_BYTES`: 3,000,000 (≈3 MB)
- - `MAX_ASSET_BYTES`: 1,500,000 (≈1.5 MB)
-- Override via environment variables in CI:
- - `TOTAL_STATIC_MAX_BYTES`
- - `MAX_ASSET_BYTES`
+### Authentication & Integration
+[![NextAuth.js][nextauth-badge]][nextauth-url]
+[![CalDAV][caldav-badge]][caldav-url]
-Artifacts
-- A budgets report is written to `.vercel/output/static-budgets-report.txt` and uploaded as a CI artifact.
+### Testing & Quality
+[![Vitest][vitest-badge]][vitest-url]
+[![ESLint][eslint-badge]][eslint-url]
+[![Prettier][prettier-badge]][prettier-url]
-Migration Dry-Run (D1)
-- The workflow attempts a best‑effort local dry‑run: `wrangler d1 execute united-tattoo --local --file=./sql/schema.sql`.
-- If local bindings are unavailable in CI, the step is skipped with a note; wire it up later when CI bindings are configured.
+
-Rollback Strategy
-- This story does not deploy. To disable CI temporarily, remove or rename the workflow file or adjust failing stages. For full rollback strategy see `docs/prd/rollback-strategy.md`.
+
+Dependencies
-## Docker
+- Next.js (App Router), React, TypeScript
+- ShadCN UI (Radix UI), Framer Motion, Tailwind CSS, Lenis, next-themes
+- React Query, Zod, React Hook Form
+- CalDAV/Calendar: tsdav, react-big-calendar, ical.js, date-fns
+- Image/file tools: Sharp, heic-convert, AWS SDK (R2)
+- Testing: Vitest, React Testing Library
-This repo is docker-ready. We build a standalone Next.js app for a smaller runtime image.
+
-Build image:
-- docker build -t united-tattoo:latest .
+(back to top)
-Run container (port 3000):
-- docker run --rm -p 3000:3000 -e PORT=3000 united-tattoo:latest
-- Open http://localhost:3000
+---
-Notes:
-- next.config.mjs sets output: "standalone"
-- The Dockerfile copies .next/standalone + .next/static and runs the server with HOSTNAME=0.0.0.0
+## Architecture
+
-## Pages Overview
+```mermaid
+graph TB
+ subgraph "Client Layer"
+ Browser[Browser]
+ end
-- Home — Bold, high-contrast, split imagery, parallax accents. This sets the identity.
-- Artists — Grid and profile surfaces wired to data/artists.ts. Each artist shows image, specialties, and sample work.
-- Aftercare — Two flows: General Aftercare and Transparent Bandage Aftercare (accurate, readable, ShadCN cards + alerts).
-- Deposit — Clear policy, payment options, and compliance notes (LW2 Investments, LLC oversight).
-- Terms & Privacy — Straightforward, legally sound, human-readable. Both accessible from the footer.
-- Booking — Multi-step form with ShadCN components and validation-friendly structure.
-- Specials — Marketing surface for time-bound promotions and membership-like advantages.
+ subgraph "Edge Layer - Cloudflare Workers"
+ NextJS[Next.js 14
App Router]
+ OpenNext[OpenNext
Adapter]
+ end
+ subgraph "Cloudflare Services"
+ D1[(D1 Database
SQLite)]
+ R2[R2 Storage
Files & Images]
+ end
-## Design Language
+ subgraph "External Services"
+ Nextcloud[Nextcloud
OAuth + CalDAV]
+ end
-- ShadCN components everywhere possible
-- Monochrome foundation with high contrast and cinematic image splits
-- Type scales + spacing match the homepage/portfolio feeling
-- Lucide icons for affordances
+ Browser --> NextJS
+ NextJS --> OpenNext
+ OpenNext --> D1
+ OpenNext --> R2
+ OpenNext <--> Nextcloud
+ style Browser fill:#667eea,color:#fff
+ style NextJS fill:#000,color:#fff
+ style OpenNext fill:#f38020,color:#fff
+ style D1 fill:#f38020,color:#fff
+ style R2 fill:#f38020,color:#fff
+ style Nextcloud fill:#0082c9,color:#fff
+```
-## Tech Notes
+
-- TypeScript errors are ignored during build in CI to allow non-blocking content/design iteration (next.config.mjs).
-- Images are unoptimized (no Next image loader), served statically; change if you plan to put this behind a CDN with transforms.
-- Smooth scroll and parallax-style offsets are kept subtle to let the work shine.
+### System Flow
+
+Authentication Flow
+
+```
+User Request → NextAuth.js
+ ↓
+ ├─ Nextcloud OAuth (Primary)
+ │ ├─ Check user groups (via OCS API)
+ │ ├─ Assign role based on group
+ │ │ ├─ "admins" → SUPER_ADMIN
+ │ │ ├─ "shop_admins" → SHOP_ADMIN
+ │ │ ├─ "artists" → ARTIST (auto-create profile)
+ │ │ └─ Other → Deny access
+ │ └─ Create/update user in D1
+ │
+ ├─ Credentials (Fallback - Admin Only)
+ │ ├─ Query parameter: ?admin=true
+ │ ├─ Email/password validation
+ │ └─ Dev mode: Auto-create SUPER_ADMIN
+ │
+ └─ Session Created (JWT)
+```
+
+
+
+
+CalDAV Sync Flow
+
+```
+Appointment Created/Updated
+ ↓
+syncAppointmentToCalendar()
+ ↓
+ ├─ Get artist's Nextcloud calendar config
+ ├─ Connect to CalDAV server
+ ├─ Create/update VEVENT
+ ├─ Store calendar_event_uid in D1
+ └─ Log sync operation
+
+Background Sync (Periodic)
+ ↓
+pullCalendarEventsToDatabase()
+ ↓
+ ├─ Fetch events from CalDAV
+ ├─ Compare with D1 appointments
+ ├─ Update changed appointments
+ ├─ Import external events
+ └─ Log sync results
+```
+
+
+
+
+Database Schema
+
+**Core Tables:**
+
+| Table | Description | Key Fields |
+|-------|-------------|------------|
+| `users` | Authentication & profiles | id, email, name, role, nextcloud_user_id |
+| `artists` | Artist profiles | id, user_id, slug, bio, specialties (JSON), hourly_rate |
+| `portfolio_images` | Artist work gallery | id, artist_id, image_url, tags (JSON), order, is_public |
+| `flash_items` | Pre-drawn designs | id, artist_id, title, price, is_available |
+| `appointments` | Booking system | id, artist_id, client_id, status, start_time, end_time, deposit |
+| `availability` | Artist schedules | id, artist_id, day_of_week, start_time, end_time |
+| `artist_calendars` | CalDAV configuration | id, artist_id, calendar_url, username, password |
+| `calendar_sync_logs` | Sync monitoring | id, artist_id, operation, status, details |
+| `site_settings` | Global config | key, value, type |
+| `file_uploads` | R2 file tracking | id, user_id, file_url, file_size, mime_type |
+
+**Indexes:** Optimized for artist lookups, appointment queries, and calendar sync operations.
+
+
+
+### Project Structure
+
+```
+united-tattoo/
+├── app/ # Next.js App Router
+│ ├── (public)/ # Public pages (no auth)
+│ │ ├── artists/ # Artist profiles & portfolios
+│ │ ├── book/ # Booking pages
+│ │ └── page.tsx # Homepage
+│ ├── admin/ # Admin dashboard (SUPER_ADMIN, SHOP_ADMIN)
+│ ├── artist-dashboard/ # Artist self-service (ARTIST)
+│ ├── api/ # API routes
+│ │ ├── artists/ # Artist CRUD
+│ │ ├── appointments/ # Booking endpoints
+│ │ ├── caldav/ # Calendar sync
+│ │ ├── flash/ # Flash items
+│ │ └── upload/ # R2 file uploads
+│ └── auth/ # NextAuth pages
+├── lib/ # Core logic
+│ ├── db.ts # D1 database functions
+│ ├── auth.ts # NextAuth config + helpers
+│ ├── caldav-client.ts # CalDAV integration
+│ ├── calendar-sync.ts # Sync logic
+│ ├── nextcloud-client.ts # Nextcloud API client
+│ ├── r2-upload.ts # R2 file handling
+│ └── env.ts # Environment validation
+├── components/ # React components
+│ ├── ui/ # ShadCN components
+│ └── ... # Feature components
+├── sql/ # Database
+│ ├── schema.sql # Main schema
+│ └── migrations/ # Migration files
+├── docs/ # Documentation
+├── .gitea/workflows/ # CI/CD pipelines
+└── wrangler.toml # Cloudflare config
+```
+
+(back to top)
+
+---
+
+## Getting Started
+
+### Prerequisites
+
+
+Required Accounts & Access
+
+Before starting, ensure you have:
+- **Cloudflare Account** with access to Workers, D1, R2, and Pages
+- **Nextcloud Instance** with admin access for OAuth app creation
+- **Node.js 18+** and npm installed
+- **Wrangler CLI** version 3+
+
+
+**Install Wrangler:**
+```bash
+npm install -g wrangler
+```
+
+**Cloudflare Resources Required:**
+- **Workers & Pages**: For hosting the application
+- **D1 Database**: SQLite database (named `united-tattoo`)
+- **R2 Buckets**: File storage (`united-tattoo`, `united-tattoo-inc-cache`)
+
+### Installation
+
+1. **Clone the repository**
+ ```bash
+ git clone https://git.biohazardvfx.com/nicholai/united-tattoo.git
+ cd united-tattoo
+ ```
+
+2. **Install dependencies**
+ ```bash
+ npm install
+ ```
+
+3. **Configure environment variables**
+ ```bash
+ cp .env.example .env.local
+ # Edit .env.local with your credentials (see Environment Variables section)
+ ```
+
+4. **Set up Cloudflare D1 database**
+ ```bash
+ # Create D1 database (if not exists)
+ wrangler d1 create united-tattoo
+
+ # Apply schema to local D1
+ npm run db:migrate:local
+
+ # Apply schema to preview/production
+ npm run db:migrate:latest:preview
+ ```
+
+5. **Configure Nextcloud OAuth**
+
+ See [`docs/NEXTCLOUD-OAUTH-SETUP.md`](docs/NEXTCLOUD-OAUTH-SETUP.md) for detailed instructions on:
+ - Creating OAuth application in Nextcloud
+ - Configuring group-based role assignment
+ - Setting up service account for CalDAV
+
+6. **Run locally**
+ ```bash
+ # Next.js dev server (port 3000)
+ npm run dev
+
+ # OR with Cloudflare Workers simulation
+ npm run dev:wrangler
+ ```
+
+7. **Access the application**
+ - Local: `http://localhost:3000`
+ - Sign in: `http://localhost:3000/auth/signin`
+ - Admin signin: `http://localhost:3000/auth/signin?admin=true`
+
+(back to top)
+
+### Environment Variables
+
+
+Required Variables
+
+| Variable | Description | Example |
+|----------|-------------|---------|
+| **Database** | | |
+| `DATABASE_URL` | PostgreSQL URL (legacy, using D1 via bindings) | `postgresql://...` |
+| `DIRECT_URL` | Direct database connection (optional) | `postgresql://...` |
+| **Authentication** | | |
+| `NEXTAUTH_URL` | Application URL | `https://united-tattoos.com` |
+| `NEXTAUTH_SECRET` | NextAuth secret key | Generate with `openssl rand -base64 32` |
+| **File Storage (Cloudflare R2)** | | |
+| `AWS_ACCESS_KEY_ID` | R2 access key ID | From Cloudflare dashboard |
+| `AWS_SECRET_ACCESS_KEY` | R2 secret access key | From Cloudflare dashboard |
+| `AWS_REGION` | Region (any valid AWS region) | `us-east-1` |
+| `AWS_BUCKET_NAME` | R2 bucket name | `united-tattoo` |
+| `AWS_ENDPOINT_URL` | R2 endpoint URL | `https://.r2.cloudflarestorage.com` |
+| **Nextcloud OAuth** | | |
+| `NEXTCLOUD_BASE_URL` | Nextcloud instance URL | `https://portal.united-tattoos.com` |
+| `NEXTCLOUD_OAUTH_CLIENT_ID` | OAuth app client ID | From Nextcloud admin |
+| `NEXTCLOUD_OAUTH_CLIENT_SECRET` | OAuth app client secret | From Nextcloud admin |
+| `NEXTCLOUD_ARTISTS_GROUP` | Group name for artists | `artists` |
+| `NEXTCLOUD_ADMINS_GROUP` | Group name for shop admins | `shop_admins` |
+
+
+
+
+Optional Variables
+
+| Variable | Description | Default |
+|----------|-------------|---------|
+| **CalDAV (Calendar Sync)** | | |
+| `NEXTCLOUD_USERNAME` | Service account username | — |
+| `NEXTCLOUD_PASSWORD` | Service account password/app password | — |
+| `NEXTCLOUD_CALENDAR_BASE_PATH` | CalDAV base path | `/remote.php/dav/calendars` |
+| **OAuth Providers (Deprecated)** | | |
+| `GOOGLE_CLIENT_ID` | Google OAuth client ID | — |
+| `GOOGLE_CLIENT_SECRET` | Google OAuth client secret | — |
+| `GITHUB_CLIENT_ID` | GitHub OAuth client ID | — |
+| `GITHUB_CLIENT_SECRET` | GitHub OAuth client secret | — |
+| **Migration** | | |
+| `MIGRATE_TOKEN` | Token for public migration endpoint | Generate random string |
+| **Analytics** | | |
+| `VERCEL_ANALYTICS_ID` | Vercel Analytics ID | — |
+
+
+
+
+Pro Tip: Use .env.local for local development and configure production variables in Cloudflare dashboard under Settings → Environment Variables.
+
+
+(back to top)
+
+---
+
+## Development
+
+### Common Commands
+
+
+
+
+| Command |
+Description |
+
+
+
+
+| Development |
+
+ npm run dev |
+ Start Next.js dev server (port 3000) |
+
+
+ npm run dev:wrangler |
+ Build and preview with OpenNext/Cloudflare |
+
+
+| Testing |
+
+ npm run test |
+ Run Vitest in watch mode |
+
+
+ npm run test:ui |
+ Run Vitest with interactive UI |
+
+
+ npm run test:run |
+ Run tests once (CI mode) |
+
+
+ npm run test:coverage |
+ Run tests with coverage report |
+
+
+| Build & Deployment |
+
+ npm run pages:build |
+ Build with OpenNext for Cloudflare |
+
+
+ npm run build |
+ Standard Next.js build (standalone) |
+
+
+ npm run preview |
+ Preview OpenNext build locally |
+
+
+ npm run deploy |
+ Deploy to Cloudflare Pages |
+
+
+| Code Quality |
+
+ npm run ci:lint |
+ Run ESLint |
+
+
+ npm run ci:typecheck |
+ TypeScript type checking (noEmit) |
+
+
+ npm run ci:test |
+ Run tests with coverage (CI) |
+
+
+ npm run ci:build |
+ Build for production (CI) |
+
+
+ npm run ci:budgets |
+ Check bundle size budgets |
+
+
+| Formatting |
+
+ npm run lint |
+ Run ESLint |
+
+
+ npm run format |
+ Format code with Prettier |
+
+
+ npm run format:check |
+ Check formatting without changing files |
+
+
+
+
+
+### Database Management
+
+
+Migration Commands
+
+**Local Database:**
+```bash
+# Apply schema to local D1
+npm run db:migrate:local
+
+# View tables in local D1
+npm run db:studio:local
+
+# Backup local database
+npm run db:backup:local
+```
+
+**Preview Environment (default):**
+```bash
+# Apply schema to preview D1
+npm run db:migrate
+
+# Apply all migrations from sql/migrations/
+npm run db:migrate:latest:preview
+
+# View tables in preview D1
+npm run db:studio
+
+# Backup preview database
+npm run db:backup
+```
+
+**Production Environment:**
+```bash
+# Apply specific migration to production
+npm run db:migrate:up:prod
+
+# Apply all migrations to production
+npm run db:migrate:latest:prod
+```
+
+**Direct Wrangler Commands:**
+```bash
+# Execute SQL query on local D1
+wrangler d1 execute united-tattoo --local --command="SELECT * FROM artists"
+
+# Apply schema file
+wrangler d1 execute united-tattoo --file=./sql/schema.sql
+
+# Execute with preview (remote)
+wrangler d1 execute united-tattoo --command="SELECT * FROM users"
+```
+
+
+
+
+Creating New Migrations
+
+1. Create migration file in `sql/migrations/` with format:
+ ```
+ YYYYMMDD_NNNN_description.sql
+ ```
+ Example: `20250130_0001_add_flash_items_table.sql`
+
+2. Write your SQL migration:
+ ```sql
+ -- Add flash_items table
+ CREATE TABLE IF NOT EXISTS flash_items (
+ id TEXT PRIMARY KEY,
+ artist_id TEXT NOT NULL,
+ title TEXT NOT NULL,
+ price REAL NOT NULL,
+ is_available INTEGER DEFAULT 1,
+ created_at TEXT DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (artist_id) REFERENCES artists(id) ON DELETE CASCADE
+ );
+ ```
+
+3. Test locally:
+ ```bash
+ npm run db:migrate:local
+ ```
+
+4. Apply to preview:
+ ```bash
+ npm run db:migrate:latest:preview
+ ```
+
+5. Apply to production (when ready):
+ ```bash
+ npm run db:migrate:latest:prod
+ ```
+
+
+
+(back to top)
+
+---
## Deployment
-- Standard Next.js deploys work (Vercel, Node server, Docker)
-- For self-hosting or VPS, use the Dockerfile in the repo
-- The site runs on port 3000 by default
+**Production URL:** [https://united-tattoos.com](https://united-tattoos.com)
+### Deployment Process
-## Why This Exists
+
+Quick Deploy Command
+npm run pages:build && wrangler deploy
+
-Because Christy deserved a proper site — and because the previous one was, bluntly, not it. United Tattoo is more than a shop. It’s a community with real people and real art. This site tries to honor that.
+**Step-by-Step:**
-— Nicholai
+1. **Build with OpenNext**
+ ```bash
+ npm run pages:build
+ ```
+ This creates a Cloudflare-compatible build in `.vercel/output/static`
+
+2. **Deploy to Cloudflare Pages**
+ ```bash
+ wrangler pages deploy .vercel/output/static
+ ```
+
+3. **Verify deployment**
+ - Check Cloudflare dashboard: Workers & Pages → united-tattoo
+ - Visit production URL: https://united-tattoos.com
+
+### CI/CD Pipeline
+
+The project uses **Gitea workflows** for automated CI/CD:
+
+**Workflows:**
+- **`ci.yaml`** - Main CI pipeline
+ - ESLint
+ - TypeScript type checking
+ - Vitest tests with coverage
+ - Production build
+ - Bundle size budgets
+
+- **`deploy.yaml`** - Automated deployments
+ - Triggers on push to `main` branch
+ - Builds and deploys to Cloudflare
+
+- **`security.yaml`** - Security audits
+ - npm audit
+ - Dependency vulnerability scanning
+
+- **`performance.yaml`** - Performance checks
+ - Bundle size analysis
+ - Preview smoke tests
+
+**Bundle Size Budgets:**
+- Total static assets: **3MB max**
+- Individual assets: **1.5MB max**
+
+Enforced by `scripts/budgets.mjs` in CI.
+
+### Docker Support
+
+
+Docker Deployment (Alternative)
+
+The project includes a Dockerfile for self-hosting:
+
+```bash
+# Build image
+docker build -t united-tattoo:latest .
+
+# Run container
+docker run --rm -p 3000:3000 \
+ -e PORT=3000 \
+ -e NEXTAUTH_URL=http://localhost:3000 \
+ -e NEXTAUTH_SECRET=your-secret \
+ # ... other env vars
+ united-tattoo:latest
+```
+
+**Note:** Docker deployment bypasses Cloudflare Workers and uses Next.js standalone mode. For production, Cloudflare deployment is recommended.
+
+
+
+(back to top)
+
+---
+
+## Documentation
+
+Comprehensive documentation is available in the [`docs/`](docs/) directory:
+
+### Key Documentation
+
+| Document | Description |
+|----------|-------------|
+| [**NEXTCLOUD-OAUTH-SETUP.md**](docs/NEXTCLOUD-OAUTH-SETUP.md) | Complete guide to setting up Nextcloud OAuth and group-based authentication |
+| [**CALDAV-SETUP.md**](docs/CALDAV-SETUP.md) | Instructions for configuring CalDAV calendar synchronization |
+| [**CI-CD-PIPELINE.md**](docs/CI-CD-PIPELINE.md) | Detailed CI/CD pipeline documentation and troubleshooting |
+| [**BOOKING-WORKFLOW-FINAL-PLAN.md**](docs/BOOKING-WORKFLOW-FINAL-PLAN.md) | Complete booking system architecture and workflow |
+
+### Additional Documentation
+
+
+View All Documentation Files
+
+**Authentication & Integration:**
+- [`CALDAV-IMPLEMENTATION-SUMMARY.md`](docs/CALDAV-IMPLEMENTATION-SUMMARY.md)
+- [`NEXTCLOUD-OAUTH-SETUP.md`](docs/NEXTCLOUD-OAUTH-SETUP.md)
+
+**Booking & Calendar:**
+- [`BOOKING-WORKFLOW-FINAL-PLAN.md`](docs/BOOKING-WORKFLOW-FINAL-PLAN.md)
+- [`BOOKING-WORKFLOW-REVISED-PLAN.md`](docs/BOOKING-WORKFLOW-REVISED-PLAN.md)
+- [`BOOKING-WORKFLOW-RISKS.md`](docs/BOOKING-WORKFLOW-RISKS.md)
+- [`CALDAV-SETUP.md`](docs/CALDAV-SETUP.md)
+
+**CI/CD & DevOps:**
+- [`CI-CD-PIPELINE.md`](docs/CI-CD-PIPELINE.md)
+- [`CI-CD-QUICK-REFERENCE.md`](docs/CI-CD-QUICK-REFERENCE.md)
+
+**Performance & SEO:**
+- [`SEO-AND-PERFORMANCE-IMPROVEMENTS.md`](docs/SEO-AND-PERFORMANCE-IMPROVEMENTS.md)
+- [`SEO-TESTING-GUIDE.md`](docs/SEO-TESTING-GUIDE.md)
+- [`PERFORMANCE-SEO-SUMMARY.md`](docs/PERFORMANCE-SEO-SUMMARY.md)
+
+**Project Management:**
+- [`PROJECT-DOCUMENTATION.md`](docs/PROJECT-DOCUMENTATION.md)
+- [`technical-decisions-template.md`](docs/technical-decisions-template.md)
+
+
+
+### AI Development Guide
+
+The project includes **[`CLAUDE.md`](CLAUDE.md)** with comprehensive instructions for AI assistants (like Claude Code) working with this codebase, including:
+- Complete architecture overview
+- Common commands reference
+- Database layer patterns
+- Authentication flows
+- CalDAV integration details
+- Development best practices
+
+(back to top)
+
+---
+
+## Roadmap
+
+### Completed Features
+
+- [x] Artist portfolio system with galleries
+- [x] Nextcloud OAuth with auto-provisioning
+- [x] CalDAV bidirectional sync
+- [x] Flash tattoo marketplace
+- [x] Admin dashboard with analytics
+- [x] Artist self-service dashboard
+- [x] Appointment booking system
+- [x] R2 file storage integration
+- [x] Role-based access control
+- [x] CI/CD pipeline with Gitea
+- [x] Bundle size enforcement
+- [x] HEIC image conversion
+- [x] Artist slug-based URLs
+
+### In Progress
+
+- [ ] Email notifications for appointments
+- [ ] SMS reminders for clients
+- [ ] Advanced calendar conflict resolution
+- [ ] Payment integration (Stripe/Square)
+- [ ] Gift card system enhancements
+- [ ] Enhanced analytics dashboard
+
+### Future Enhancements
+
+- [ ] Client self-service portal
+- [ ] Online deposit payments
+- [ ] Artist earnings reports
+- [ ] Inventory management
+- [ ] Social media auto-posting
+- [ ] Mobile app (React Native)
+- [ ] Webhook integrations
+- [ ] Advanced reporting
+
+See the [open issues](https://git.biohazardvfx.com/nicholai/united-tattoo/issues) for a full list of proposed features and known issues.
+
+(back to top)
+
+---
+
+## Contributing
+
+Contributions are welcome! This project follows standard Git workflows and conventional commits.
+
+### Development Workflow
+
+1. **Fork the project**
+ ```bash
+ # Via Gitea UI or git clone
+ git clone https://git.biohazardvfx.com/nicholai/united-tattoo.git
+ ```
+
+2. **Create your feature branch**
+ ```bash
+ git checkout -b feat/amazing-feature
+ ```
+
+3. **Make your changes**
+ - Follow existing code style (enforced by ESLint/Prettier)
+ - Add tests for new features
+ - Update documentation as needed
+
+4. **Run quality checks**
+ ```bash
+ npm run lint # Check linting
+ npm run format # Format code
+ npm run ci:typecheck # Check types
+ npm run test:run # Run tests
+ npm run ci:budgets # Check bundle sizes
+ ```
+
+5. **Commit your changes**
+ ```bash
+ git add .
+ git commit -m "feat: add amazing feature"
+ ```
+
+ Use [Conventional Commits](https://www.conventionalcommits.org/) format:
+ - `feat:` New feature
+ - `fix:` Bug fix
+ - `docs:` Documentation changes
+ - `style:` Formatting, missing semicolons, etc.
+ - `refactor:` Code refactoring
+ - `test:` Adding tests
+ - `chore:` Maintenance tasks
+
+6. **Push to your branch**
+ ```bash
+ git push origin feat/amazing-feature
+ ```
+
+7. **Open a Pull Request**
+ - Via Gitea UI
+ - Provide clear description of changes
+ - Reference any related issues
+
+### Code Style Guidelines
+
+- **TypeScript**: Prefer strict typing, avoid `any`
+- **React**: Use functional components with hooks
+- **File organization**: Keep components modular
+- **Comments**: Explain "why", not "what"
+- **Tests**: Test user-facing behavior, not implementation
+
+### Top Contributors
+
+
+
+
+
+(back to top)
+
+---
+
+## License
+
+
+
License Status
+This project currently does not have a LICENSE file in the repository. If you intend to use GNU GPLv3 (as referenced in the original README template), please add a
LICENSE or
COPYING file with the full license text.
+
+Alternatively, consider:
+-
MIT License - Permissive, allows commercial use
+-
Apache 2.0 - Permissive with patent grant
+-
GNU GPLv3 - Copyleft, requires source disclosure
+-
Proprietary - All rights reserved
+
+
Choose A License can help you decide.
+
+
+**Current Status:** No license specified. Please add a LICENSE file to clarify usage terms.
+
+(back to top)
+
+---
+
+## Contact
+
+
+
+**Nicholai Vogel**
+
+[](https://nicholai.work)
+[](https://linkedin.com/in/nicholai-vogel)
+[](https://instagram.com/nicholai.exe)
+
+**Project Repository**
+[https://git.biohazardvfx.com/nicholai/united-tattoo](https://git.biohazardvfx.com/nicholai/united-tattoo)
+
+**Live Website**
+[https://united-tattoos.com](https://united-tattoos.com)
+
+
+
+---
+
+
+
+### Star this repository if you find it helpful!
+
+
(back to top)
+
+---
+
+**Made with love for United Tattoo Studio, Fountain, CO**
+
+
+
+
+[contributors-shield]: https://img.shields.io/badge/Contributors-1-667eea?style=for-the-badge
+[contributors-url]: https://git.biohazardvfx.com/nicholai/united-tattoo/graphs/contributors
+[forks-shield]: https://img.shields.io/badge/Forks-0-667eea?style=for-the-badge
+[forks-url]: https://git.biohazardvfx.com/nicholai/united-tattoo/network/members
+[stars-shield]: https://img.shields.io/badge/Stars-0-667eea?style=for-the-badge
+[stars-url]: https://git.biohazardvfx.com/nicholai/united-tattoo/stargazers
+[issues-shield]: https://img.shields.io/badge/Issues-0-667eea?style=for-the-badge
+[issues-url]: https://git.biohazardvfx.com/nicholai/united-tattoo/issues
+[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=0077B5
+[linkedin-url]: https://linkedin.com/in/nicholai-vogel
+
+[nextjs-badge]: https://img.shields.io/badge/Next.js_14-000000?style=for-the-badge&logo=nextdotjs&logoColor=white
+[next-url]: https://nextjs.org/
+[react-badge]: https://img.shields.io/badge/React_18-20232A?style=for-the-badge&logo=react&logoColor=61DAFB
+[react-url]: https://react.dev/
+[typescript-badge]: https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white
+[typescript-url]: https://www.typescriptlang.org/
+[cloudflare-badge]: https://img.shields.io/badge/Cloudflare_Workers-F38020?style=for-the-badge&logo=cloudflare&logoColor=white
+[cloudflare-url]: https://developers.cloudflare.com/workers/
+[opennext-badge]: https://img.shields.io/badge/OpenNext-18181B?style=for-the-badge&logo=vercel&logoColor=white
+[opennext-url]: https://opennext.js.org/
+[shadcn-badge]: https://img.shields.io/badge/ShadCN_UI-000000?style=for-the-badge&logo=shadcnui&logoColor=white
+[shadcn-url]: https://ui.shadcn.com
+[tailwind-badge]: https://img.shields.io/badge/Tailwind_CSS-38B2AC?style=for-the-badge&logo=tailwind-css&logoColor=white
+[tailwind-url]: https://tailwindcss.com
+[framer-badge]: https://img.shields.io/badge/Framer_Motion-0055FF?style=for-the-badge&logo=framer&logoColor=white
+[framer-url]: https://www.framer.com/motion/
+[d1-badge]: https://img.shields.io/badge/D1_Database-F38020?style=for-the-badge&logo=cloudflare&logoColor=white
+[d1-url]: https://developers.cloudflare.com/d1/
+[r2-badge]: https://img.shields.io/badge/R2_Storage-F38020?style=for-the-badge&logo=cloudflare&logoColor=white
+[r2-url]: https://developers.cloudflare.com/r2/
+[nextauth-badge]: https://img.shields.io/badge/NextAuth.js-000000?style=for-the-badge&logo=nextdotjs&logoColor=white
+[nextauth-url]: https://next-auth.js.org/
+[caldav-badge]: https://img.shields.io/badge/CalDAV-0082C9?style=for-the-badge&logo=nextcloud&logoColor=white
+[caldav-url]: https://en.wikipedia.org/wiki/CalDAV
+[vitest-badge]: https://img.shields.io/badge/Vitest-6E9F18?style=for-the-badge&logo=vitest&logoColor=white
+[vitest-url]: https://vitest.dev/
+[eslint-badge]: https://img.shields.io/badge/ESLint-4B32C3?style=for-the-badge&logo=eslint&logoColor=white
+[eslint-url]: https://eslint.org/
+[prettier-badge]: https://img.shields.io/badge/Prettier-F7B93E?style=for-the-badge&logo=prettier&logoColor=black
+[prettier-url]: https://prettier.io/