feat: Add CHORUS teaser website with mobile-responsive design

- Created complete Next.js 15 teaser website with CHORUS brand styling
- Implemented mobile-responsive 3D logo (128px mobile, 512px desktop)
- Added proper Exo font loading via Next.js Google Fonts for iOS/Chrome compatibility
- Built comprehensive early access form with GDPR compliance and rate limiting
- Integrated PostgreSQL database with complete schema for lead capture
- Added scroll indicators that auto-hide when scrolling begins
- Optimized mobile modal forms with proper scrolling and submit button access
- Deployed via Docker Swarm with Traefik SSL termination at chorus.services
- Includes database migrations, consent tracking, and email notifications

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
tony
2025-08-26 13:57:30 +10:00
parent 630d1c26ad
commit c8fb816775
236 changed files with 17525 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
version: '3.8'
services:
# PostgreSQL Database
postgres:
image: postgres:15-alpine
container_name: chorus-teaser-postgres
restart: unless-stopped
environment:
POSTGRES_DB: chorus_website
POSTGRES_USER: chorus
POSTGRES_PASSWORD: choruspass
POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=en_US.UTF-8"
ports:
- "5434:5432"
volumes:
- teaser-postgres-data:/var/lib/postgresql/data
- ./database:/docker-entrypoint-initdb.d
networks:
- teaser-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U chorus -d chorus_website"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
# Next.js Teaser Website
teaser:
build:
context: .
dockerfile: Dockerfile
container_name: chorus-teaser
restart: unless-stopped
ports:
- "3001:3000"
environment:
- NODE_ENV=production
- NEXT_TELEMETRY_DISABLED=1
- PORT=3000
- DATABASE_URL=postgresql://chorus:choruspass@postgres:5432/chorus_website
- SMTP_HOST=${SMTP_HOST:-smtp.gmail.com}
- SMTP_PORT=${SMTP_PORT:-587}
- SMTP_USER=${SMTP_USER}
- SMTP_PASS=${SMTP_PASS}
- NOTIFICATION_FROM_EMAIL=${NOTIFICATION_FROM_EMAIL:-noreply@chorus.services}
- NOTIFICATION_TO_EMAIL=${NOTIFICATION_TO_EMAIL:-anthony.lewis.rawlins@gmail.com}
- LEAD_API_KEY=${LEAD_API_KEY:-dev-api-key-chorus-teaser}
depends_on:
postgres:
condition: service_healthy
volumes:
- teaser-logs:/app/logs
networks:
- teaser-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 40s
labels:
- "traefik.enable=true"
- "traefik.http.routers.teaser.rule=Host(`teaser.chorus.services`)"
- "traefik.http.routers.teaser.tls=true"
- "traefik.http.services.teaser.loadbalancer.server.port=3000"
# Redis for session/rate limiting
redis:
image: redis:7-alpine
container_name: chorus-teaser-redis
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- teaser-redis-data:/data
networks:
- teaser-network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 3s
retries: 3
volumes:
teaser-logs:
driver: local
teaser-redis-data:
driver: local
teaser-postgres-data:
driver: local
networks:
teaser-network:
driver: bridge