feat: initial Next.js 15 implementation with TypeScript and Tailwind CSS 4
Add complete project structure and foundation:
**Core Setup:**
- Next.js 15.5.6 with App Router and React 19
- TypeScript 5.7 with strict mode
- Tailwind CSS 4.1 with custom theme configuration
- ESLint and Prettier configuration
**Dependencies Installed:**
- @tanstack/react-query - Server state management
- zustand - Client state management
- framer-motion - Animations
- lucide-react - Icon library
- react-colorful - Color picker component
- cmdk - Command palette
- sonner - Toast notifications
- clsx + tailwind-merge - Class name utilities
**Project Structure:**
- app/ - Next.js App Router pages
- components/ - React components (ui, color, tools, layout, providers)
- lib/ - Utilities, API client, hooks, stores, constants
- tests/ - Unit and E2E test directories
**API Integration:**
- Type-safe Pastel API client with all 21 endpoints
- Complete TypeScript type definitions for requests/responses
- Error handling and response types
**UI Components:**
- Button component with variants (default, outline, ghost, destructive)
- Input component with focus states
- Providers wrapper (React Query, Toast)
- Root layout with Inter font and metadata
**Pages:**
- Home page with gradient hero and feature cards
- Links to playground and palette generation (pages pending)
**Configuration:**
- Tailwind with HSL color variables for theming
- Dark/light mode CSS variables
- Custom animations (fade-in, slide-up, slide-down)
- @tailwindcss/forms and @tailwindcss/typography plugins
Build successful: 102 kB First Load JS, static generation working.
Ready for color components and playground implementation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 10:55:42 +01:00
|
|
|
import type {
|
|
|
|
|
ApiResponse,
|
|
|
|
|
ColorInfoRequest,
|
|
|
|
|
ColorInfoData,
|
|
|
|
|
ConvertFormatRequest,
|
|
|
|
|
ConvertFormatData,
|
|
|
|
|
ColorManipulationRequest,
|
|
|
|
|
ColorManipulationData,
|
|
|
|
|
ColorMixRequest,
|
|
|
|
|
ColorMixData,
|
|
|
|
|
RandomColorsRequest,
|
|
|
|
|
RandomColorsData,
|
|
|
|
|
DistinctColorsRequest,
|
|
|
|
|
DistinctColorsData,
|
|
|
|
|
GradientRequest,
|
|
|
|
|
GradientData,
|
|
|
|
|
ColorDistanceRequest,
|
|
|
|
|
ColorDistanceData,
|
|
|
|
|
ColorSortRequest,
|
|
|
|
|
ColorSortData,
|
|
|
|
|
ColorBlindnessRequest,
|
|
|
|
|
ColorBlindnessData,
|
|
|
|
|
TextColorRequest,
|
|
|
|
|
TextColorData,
|
|
|
|
|
NamedColorsData,
|
|
|
|
|
NamedColorSearchRequest,
|
|
|
|
|
NamedColorSearchData,
|
|
|
|
|
HealthData,
|
|
|
|
|
CapabilitiesData,
|
2025-11-07 14:33:38 +01:00
|
|
|
PaletteGenerateRequest,
|
|
|
|
|
PaletteGenerateData,
|
feat: initial Next.js 15 implementation with TypeScript and Tailwind CSS 4
Add complete project structure and foundation:
**Core Setup:**
- Next.js 15.5.6 with App Router and React 19
- TypeScript 5.7 with strict mode
- Tailwind CSS 4.1 with custom theme configuration
- ESLint and Prettier configuration
**Dependencies Installed:**
- @tanstack/react-query - Server state management
- zustand - Client state management
- framer-motion - Animations
- lucide-react - Icon library
- react-colorful - Color picker component
- cmdk - Command palette
- sonner - Toast notifications
- clsx + tailwind-merge - Class name utilities
**Project Structure:**
- app/ - Next.js App Router pages
- components/ - React components (ui, color, tools, layout, providers)
- lib/ - Utilities, API client, hooks, stores, constants
- tests/ - Unit and E2E test directories
**API Integration:**
- Type-safe Pastel API client with all 21 endpoints
- Complete TypeScript type definitions for requests/responses
- Error handling and response types
**UI Components:**
- Button component with variants (default, outline, ghost, destructive)
- Input component with focus states
- Providers wrapper (React Query, Toast)
- Root layout with Inter font and metadata
**Pages:**
- Home page with gradient hero and feature cards
- Links to playground and palette generation (pages pending)
**Configuration:**
- Tailwind with HSL color variables for theming
- Dark/light mode CSS variables
- Custom animations (fade-in, slide-up, slide-down)
- @tailwindcss/forms and @tailwindcss/typography plugins
Build successful: 102 kB First Load JS, static generation working.
Ready for color components and playground implementation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 10:55:42 +01:00
|
|
|
} from './types';
|
feat: integrate WebAssembly for zero-latency, offline-first color operations
Replaced REST API dependency with @valknarthing/pastel-wasm (130KB) for
complete browser-based color operations. The application is now fully
static (2.2MB total) with zero network latency and offline support.
**Key Changes:**
1. **WASM Integration:**
- Added @valknarthing/pastel-wasm dependency (0.1.0)
- Created lib/api/wasm-client.ts wrapper matching API interface
- Updated lib/api/client.ts to use WASM client by default
- All 18 color operations now run locally in browser
2. **Static Export Configuration:**
- Changed next.config.ts output from 'standalone' to 'export'
- Disabled image optimization for static export
- Removed API proxy route (app/api/pastel/[...path]/route.ts)
- Updated package.json scripts (removed dev:api, added serve)
3. **Docker Optimization:**
- Migrated from Node.js standalone to nginx-alpine
- Created nginx.conf with SPA routing and WASM mime types
- Updated Dockerfile for static file serving
- Reduced image size from ~150MB to ~25MB
- Changed port from 3000 to 80 (standard HTTP)
- Simplified docker-compose.yml (removed pastel-api service)
4. **Documentation Updates:**
- Updated README.md with WASM benefits and deployment options
- Added Key Benefits section highlighting zero-latency features
- Rewrote deployment section for static hosting platforms
- Updated CLAUDE.md tech stack and architecture
- Removed obsolete docs: DEV_SETUP.md, DOCKER.md, IMPLEMENTATION_PLAN.md
**Benefits:**
- 🚀 Zero Latency - All operations run locally via WebAssembly
- 📱 Offline First - Works completely offline after initial load
- 🌐 No Backend - Fully static, deploy anywhere
- ⚡ Fast - Native-speed color operations in browser
- 📦 Small - 2.2MB total (130KB WASM, 2.07MB HTML/CSS/JS)
**Deployment:**
Can now be deployed to any static hosting platform:
- Vercel, Netlify, Cloudflare Pages (zero config)
- GitHub Pages, S3, CDN
- Self-hosted nginx/Apache
- Docker (optional, nginx-based)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 09:06:25 +01:00
|
|
|
import { pastelWASM } from './wasm-client';
|
feat: initial Next.js 15 implementation with TypeScript and Tailwind CSS 4
Add complete project structure and foundation:
**Core Setup:**
- Next.js 15.5.6 with App Router and React 19
- TypeScript 5.7 with strict mode
- Tailwind CSS 4.1 with custom theme configuration
- ESLint and Prettier configuration
**Dependencies Installed:**
- @tanstack/react-query - Server state management
- zustand - Client state management
- framer-motion - Animations
- lucide-react - Icon library
- react-colorful - Color picker component
- cmdk - Command palette
- sonner - Toast notifications
- clsx + tailwind-merge - Class name utilities
**Project Structure:**
- app/ - Next.js App Router pages
- components/ - React components (ui, color, tools, layout, providers)
- lib/ - Utilities, API client, hooks, stores, constants
- tests/ - Unit and E2E test directories
**API Integration:**
- Type-safe Pastel API client with all 21 endpoints
- Complete TypeScript type definitions for requests/responses
- Error handling and response types
**UI Components:**
- Button component with variants (default, outline, ghost, destructive)
- Input component with focus states
- Providers wrapper (React Query, Toast)
- Root layout with Inter font and metadata
**Pages:**
- Home page with gradient hero and feature cards
- Links to playground and palette generation (pages pending)
**Configuration:**
- Tailwind with HSL color variables for theming
- Dark/light mode CSS variables
- Custom animations (fade-in, slide-up, slide-down)
- @tailwindcss/forms and @tailwindcss/typography plugins
Build successful: 102 kB First Load JS, static generation working.
Ready for color components and playground implementation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 10:55:42 +01:00
|
|
|
|
|
|
|
|
export class PastelAPIClient {
|
|
|
|
|
private baseURL: string;
|
|
|
|
|
|
|
|
|
|
constructor(baseURL?: string) {
|
2025-11-07 16:05:55 +01:00
|
|
|
// Use the Next.js API proxy route for runtime configuration
|
|
|
|
|
// This allows changing the backend API URL without rebuilding
|
|
|
|
|
this.baseURL = baseURL || '/api/pastel';
|
feat: initial Next.js 15 implementation with TypeScript and Tailwind CSS 4
Add complete project structure and foundation:
**Core Setup:**
- Next.js 15.5.6 with App Router and React 19
- TypeScript 5.7 with strict mode
- Tailwind CSS 4.1 with custom theme configuration
- ESLint and Prettier configuration
**Dependencies Installed:**
- @tanstack/react-query - Server state management
- zustand - Client state management
- framer-motion - Animations
- lucide-react - Icon library
- react-colorful - Color picker component
- cmdk - Command palette
- sonner - Toast notifications
- clsx + tailwind-merge - Class name utilities
**Project Structure:**
- app/ - Next.js App Router pages
- components/ - React components (ui, color, tools, layout, providers)
- lib/ - Utilities, API client, hooks, stores, constants
- tests/ - Unit and E2E test directories
**API Integration:**
- Type-safe Pastel API client with all 21 endpoints
- Complete TypeScript type definitions for requests/responses
- Error handling and response types
**UI Components:**
- Button component with variants (default, outline, ghost, destructive)
- Input component with focus states
- Providers wrapper (React Query, Toast)
- Root layout with Inter font and metadata
**Pages:**
- Home page with gradient hero and feature cards
- Links to playground and palette generation (pages pending)
**Configuration:**
- Tailwind with HSL color variables for theming
- Dark/light mode CSS variables
- Custom animations (fade-in, slide-up, slide-down)
- @tailwindcss/forms and @tailwindcss/typography plugins
Build successful: 102 kB First Load JS, static generation working.
Ready for color components and playground implementation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 10:55:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async request<T>(
|
|
|
|
|
endpoint: string,
|
|
|
|
|
options?: RequestInit
|
|
|
|
|
): Promise<ApiResponse<T>> {
|
2025-11-07 16:05:55 +01:00
|
|
|
// Endpoint already includes /api/v1 prefix on backend,
|
|
|
|
|
// but our proxy route expects paths after /api/v1/
|
|
|
|
|
const url = `${this.baseURL}${endpoint}`;
|
feat: initial Next.js 15 implementation with TypeScript and Tailwind CSS 4
Add complete project structure and foundation:
**Core Setup:**
- Next.js 15.5.6 with App Router and React 19
- TypeScript 5.7 with strict mode
- Tailwind CSS 4.1 with custom theme configuration
- ESLint and Prettier configuration
**Dependencies Installed:**
- @tanstack/react-query - Server state management
- zustand - Client state management
- framer-motion - Animations
- lucide-react - Icon library
- react-colorful - Color picker component
- cmdk - Command palette
- sonner - Toast notifications
- clsx + tailwind-merge - Class name utilities
**Project Structure:**
- app/ - Next.js App Router pages
- components/ - React components (ui, color, tools, layout, providers)
- lib/ - Utilities, API client, hooks, stores, constants
- tests/ - Unit and E2E test directories
**API Integration:**
- Type-safe Pastel API client with all 21 endpoints
- Complete TypeScript type definitions for requests/responses
- Error handling and response types
**UI Components:**
- Button component with variants (default, outline, ghost, destructive)
- Input component with focus states
- Providers wrapper (React Query, Toast)
- Root layout with Inter font and metadata
**Pages:**
- Home page with gradient hero and feature cards
- Links to playground and palette generation (pages pending)
**Configuration:**
- Tailwind with HSL color variables for theming
- Dark/light mode CSS variables
- Custom animations (fade-in, slide-up, slide-down)
- @tailwindcss/forms and @tailwindcss/typography plugins
Build successful: 102 kB First Load JS, static generation working.
Ready for color components and playground implementation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 10:55:42 +01:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const response = await fetch(url, {
|
|
|
|
|
...options,
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
...options?.headers,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
return {
|
|
|
|
|
success: false,
|
|
|
|
|
error: data.error || {
|
|
|
|
|
code: 'INTERNAL_ERROR',
|
|
|
|
|
message: 'An unknown error occurred',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return data;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
return {
|
|
|
|
|
success: false,
|
|
|
|
|
error: {
|
|
|
|
|
code: 'NETWORK_ERROR',
|
|
|
|
|
message: error instanceof Error ? error.message : 'Network request failed',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Color Information
|
|
|
|
|
async getColorInfo(request: ColorInfoRequest): Promise<ApiResponse<ColorInfoData>> {
|
|
|
|
|
return this.request<ColorInfoData>('/colors/info', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Format Conversion
|
|
|
|
|
async convertFormat(request: ConvertFormatRequest): Promise<ApiResponse<ConvertFormatData>> {
|
|
|
|
|
return this.request<ConvertFormatData>('/colors/convert', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Color Manipulation
|
|
|
|
|
async lighten(request: ColorManipulationRequest): Promise<ApiResponse<ColorManipulationData>> {
|
|
|
|
|
return this.request<ColorManipulationData>('/colors/lighten', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async darken(request: ColorManipulationRequest): Promise<ApiResponse<ColorManipulationData>> {
|
|
|
|
|
return this.request<ColorManipulationData>('/colors/darken', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async saturate(request: ColorManipulationRequest): Promise<ApiResponse<ColorManipulationData>> {
|
|
|
|
|
return this.request<ColorManipulationData>('/colors/saturate', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async desaturate(request: ColorManipulationRequest): Promise<ApiResponse<ColorManipulationData>> {
|
|
|
|
|
return this.request<ColorManipulationData>('/colors/desaturate', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async rotate(request: ColorManipulationRequest): Promise<ApiResponse<ColorManipulationData>> {
|
|
|
|
|
return this.request<ColorManipulationData>('/colors/rotate', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async complement(colors: string[]): Promise<ApiResponse<ColorManipulationData>> {
|
|
|
|
|
return this.request<ColorManipulationData>('/colors/complement', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify({ colors }),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async grayscale(colors: string[]): Promise<ApiResponse<ColorManipulationData>> {
|
|
|
|
|
return this.request<ColorManipulationData>('/colors/grayscale', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify({ colors }),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async mix(request: ColorMixRequest): Promise<ApiResponse<ColorMixData>> {
|
|
|
|
|
return this.request<ColorMixData>('/colors/mix', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Color Generation
|
|
|
|
|
async generateRandom(request: RandomColorsRequest): Promise<ApiResponse<RandomColorsData>> {
|
|
|
|
|
return this.request<RandomColorsData>('/colors/random', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async generateDistinct(request: DistinctColorsRequest): Promise<ApiResponse<DistinctColorsData>> {
|
|
|
|
|
return this.request<DistinctColorsData>('/colors/distinct', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async generateGradient(request: GradientRequest): Promise<ApiResponse<GradientData>> {
|
|
|
|
|
return this.request<GradientData>('/colors/gradient', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Color Analysis
|
|
|
|
|
async calculateDistance(request: ColorDistanceRequest): Promise<ApiResponse<ColorDistanceData>> {
|
|
|
|
|
return this.request<ColorDistanceData>('/colors/distance', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async sortColors(request: ColorSortRequest): Promise<ApiResponse<ColorSortData>> {
|
|
|
|
|
return this.request<ColorSortData>('/colors/sort', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Accessibility
|
2025-11-07 14:33:38 +01:00
|
|
|
async simulateColorBlindness(request: ColorBlindnessRequest): Promise<ApiResponse<ColorBlindnessData>> {
|
feat: initial Next.js 15 implementation with TypeScript and Tailwind CSS 4
Add complete project structure and foundation:
**Core Setup:**
- Next.js 15.5.6 with App Router and React 19
- TypeScript 5.7 with strict mode
- Tailwind CSS 4.1 with custom theme configuration
- ESLint and Prettier configuration
**Dependencies Installed:**
- @tanstack/react-query - Server state management
- zustand - Client state management
- framer-motion - Animations
- lucide-react - Icon library
- react-colorful - Color picker component
- cmdk - Command palette
- sonner - Toast notifications
- clsx + tailwind-merge - Class name utilities
**Project Structure:**
- app/ - Next.js App Router pages
- components/ - React components (ui, color, tools, layout, providers)
- lib/ - Utilities, API client, hooks, stores, constants
- tests/ - Unit and E2E test directories
**API Integration:**
- Type-safe Pastel API client with all 21 endpoints
- Complete TypeScript type definitions for requests/responses
- Error handling and response types
**UI Components:**
- Button component with variants (default, outline, ghost, destructive)
- Input component with focus states
- Providers wrapper (React Query, Toast)
- Root layout with Inter font and metadata
**Pages:**
- Home page with gradient hero and feature cards
- Links to playground and palette generation (pages pending)
**Configuration:**
- Tailwind with HSL color variables for theming
- Dark/light mode CSS variables
- Custom animations (fade-in, slide-up, slide-down)
- @tailwindcss/forms and @tailwindcss/typography plugins
Build successful: 102 kB First Load JS, static generation working.
Ready for color components and playground implementation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 10:55:42 +01:00
|
|
|
return this.request<ColorBlindnessData>('/colors/colorblind', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getTextColor(request: TextColorRequest): Promise<ApiResponse<TextColorData>> {
|
|
|
|
|
return this.request<TextColorData>('/colors/textcolor', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Named Colors
|
|
|
|
|
async getNamedColors(): Promise<ApiResponse<NamedColorsData>> {
|
|
|
|
|
return this.request<NamedColorsData>('/colors/names', {
|
|
|
|
|
method: 'GET',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async searchNamedColors(request: NamedColorSearchRequest): Promise<ApiResponse<NamedColorSearchData>> {
|
|
|
|
|
return this.request<NamedColorSearchData>('/colors/names/search', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// System
|
|
|
|
|
async getHealth(): Promise<ApiResponse<HealthData>> {
|
|
|
|
|
return this.request<HealthData>('/health', {
|
|
|
|
|
method: 'GET',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getCapabilities(): Promise<ApiResponse<CapabilitiesData>> {
|
|
|
|
|
return this.request<CapabilitiesData>('/capabilities', {
|
|
|
|
|
method: 'GET',
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-11-07 14:33:38 +01:00
|
|
|
|
|
|
|
|
// Palette Generation
|
|
|
|
|
async generatePalette(request: PaletteGenerateRequest): Promise<ApiResponse<PaletteGenerateData>> {
|
|
|
|
|
return this.request<PaletteGenerateData>('/palettes/generate', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(request),
|
|
|
|
|
});
|
|
|
|
|
}
|
feat: initial Next.js 15 implementation with TypeScript and Tailwind CSS 4
Add complete project structure and foundation:
**Core Setup:**
- Next.js 15.5.6 with App Router and React 19
- TypeScript 5.7 with strict mode
- Tailwind CSS 4.1 with custom theme configuration
- ESLint and Prettier configuration
**Dependencies Installed:**
- @tanstack/react-query - Server state management
- zustand - Client state management
- framer-motion - Animations
- lucide-react - Icon library
- react-colorful - Color picker component
- cmdk - Command palette
- sonner - Toast notifications
- clsx + tailwind-merge - Class name utilities
**Project Structure:**
- app/ - Next.js App Router pages
- components/ - React components (ui, color, tools, layout, providers)
- lib/ - Utilities, API client, hooks, stores, constants
- tests/ - Unit and E2E test directories
**API Integration:**
- Type-safe Pastel API client with all 21 endpoints
- Complete TypeScript type definitions for requests/responses
- Error handling and response types
**UI Components:**
- Button component with variants (default, outline, ghost, destructive)
- Input component with focus states
- Providers wrapper (React Query, Toast)
- Root layout with Inter font and metadata
**Pages:**
- Home page with gradient hero and feature cards
- Links to playground and palette generation (pages pending)
**Configuration:**
- Tailwind with HSL color variables for theming
- Dark/light mode CSS variables
- Custom animations (fade-in, slide-up, slide-down)
- @tailwindcss/forms and @tailwindcss/typography plugins
Build successful: 102 kB First Load JS, static generation working.
Ready for color components and playground implementation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 10:55:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Export singleton instance
|
feat: integrate WebAssembly for zero-latency, offline-first color operations
Replaced REST API dependency with @valknarthing/pastel-wasm (130KB) for
complete browser-based color operations. The application is now fully
static (2.2MB total) with zero network latency and offline support.
**Key Changes:**
1. **WASM Integration:**
- Added @valknarthing/pastel-wasm dependency (0.1.0)
- Created lib/api/wasm-client.ts wrapper matching API interface
- Updated lib/api/client.ts to use WASM client by default
- All 18 color operations now run locally in browser
2. **Static Export Configuration:**
- Changed next.config.ts output from 'standalone' to 'export'
- Disabled image optimization for static export
- Removed API proxy route (app/api/pastel/[...path]/route.ts)
- Updated package.json scripts (removed dev:api, added serve)
3. **Docker Optimization:**
- Migrated from Node.js standalone to nginx-alpine
- Created nginx.conf with SPA routing and WASM mime types
- Updated Dockerfile for static file serving
- Reduced image size from ~150MB to ~25MB
- Changed port from 3000 to 80 (standard HTTP)
- Simplified docker-compose.yml (removed pastel-api service)
4. **Documentation Updates:**
- Updated README.md with WASM benefits and deployment options
- Added Key Benefits section highlighting zero-latency features
- Rewrote deployment section for static hosting platforms
- Updated CLAUDE.md tech stack and architecture
- Removed obsolete docs: DEV_SETUP.md, DOCKER.md, IMPLEMENTATION_PLAN.md
**Benefits:**
- 🚀 Zero Latency - All operations run locally via WebAssembly
- 📱 Offline First - Works completely offline after initial load
- 🌐 No Backend - Fully static, deploy anywhere
- ⚡ Fast - Native-speed color operations in browser
- 📦 Small - 2.2MB total (130KB WASM, 2.07MB HTML/CSS/JS)
**Deployment:**
Can now be deployed to any static hosting platform:
- Vercel, Netlify, Cloudflare Pages (zero config)
- GitHub Pages, S3, CDN
- Self-hosted nginx/Apache
- Docker (optional, nginx-based)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 09:06:25 +01:00
|
|
|
// Now using WASM client for zero-latency, offline-first color operations
|
|
|
|
|
export const pastelAPI = pastelWASM;
|