From 484423f299f86c2ba472ea46ddbb4ce156b22c2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Thu, 26 Feb 2026 12:19:22 +0100 Subject: [PATCH] refactor: rename pastel app to color and update all references --- GEMINI.md | 6 ++--- README.md | 10 +++---- app/(app)/{pastel => color}/globals.css | 9 ------- app/(app)/{pastel => color}/layout.tsx | 2 +- app/(app)/{pastel => color}/page.tsx | 18 ++++++------- app/layout.tsx | 2 +- components/AppIcons.tsx | 2 +- components/ToolsGrid.tsx | 8 +++--- components/{pastel => color}/ColorDisplay.tsx | 0 components/{pastel => color}/ColorInfo.tsx | 2 +- components/{pastel => color}/ColorPicker.tsx | 2 +- components/{pastel => color}/ColorSwatch.tsx | 0 components/{pastel => color}/ExportMenu.tsx | 6 ++--- .../{pastel => color}/ManipulationPanel.tsx | 2 +- components/{pastel => color}/PaletteGrid.tsx | 0 components/layout/AppSidebar.tsx | 8 +++--- lib/{pastel => color}/api/client.ts | 8 +++--- lib/{pastel => color}/api/queries.ts | 26 +++++++++---------- lib/{pastel => color}/api/types.ts | 0 lib/{pastel => color}/api/wasm-client.ts | 8 +++--- lib/{pastel => color}/index.ts | 0 lib/{pastel => color}/utils/color.ts | 0 lib/{pastel => color}/utils/export.ts | 0 23 files changed, 55 insertions(+), 64 deletions(-) rename app/(app)/{pastel => color}/globals.css (93%) rename app/(app)/{pastel => color}/layout.tsx (74%) rename app/(app)/{pastel => color}/page.tsx (96%) rename components/{pastel => color}/ColorDisplay.tsx (100%) rename components/{pastel => color}/ColorInfo.tsx (98%) rename components/{pastel => color}/ColorPicker.tsx (97%) rename components/{pastel => color}/ColorSwatch.tsx (100%) rename components/{pastel => color}/ExportMenu.tsx (97%) rename components/{pastel => color}/ManipulationPanel.tsx (99%) rename components/{pastel => color}/PaletteGrid.tsx (100%) rename lib/{pastel => color}/api/client.ts (96%) rename lib/{pastel => color}/api/queries.ts (83%) rename lib/{pastel => color}/api/types.ts (100%) rename lib/{pastel => color}/api/wasm-client.ts (98%) rename lib/{pastel => color}/index.ts (100%) rename lib/{pastel => color}/utils/color.ts (100%) rename lib/{pastel => color}/utils/export.ts (100%) diff --git a/GEMINI.md b/GEMINI.md index 59c10cb..9298e31 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -6,7 +6,7 @@ This file provides foundational context and instructions for Gemini CLI when wor **Kit UI** is a high-performance, aesthetically pleasing toolkit built with **Next.js 16**, **React 19**, and **Tailwind CSS 4**. It provides four core specialized applications: -1. **Pastel**: Advanced color theory, manipulation, and accessibility suite powered by `@valknarthing/pastel-wasm`. +1. **Color**: Advanced color theory, manipulation, and accessibility suite powered by `@valknarthing/pastel-wasm`. 2. **Units**: Smart unit converter supporting 187+ units across 23 categories, including a custom `tempo` measure. 3. **Figlet**: ASCII Art generator with 373 fonts and multi-format export. 4. **Media**: Browser-based file converter using **FFmpeg** and **ImageMagick** via WebAssembly (Zero server uploads). @@ -26,10 +26,10 @@ This file provides foundational context and instructions for Gemini CLI when wor ```bash . ├── app/ # Next.js App Router -│ ├── (app)/ # Core Tool Pages (pastel, units, figlet, media) +│ ├── (app)/ # Core Tool Pages (color, units, figlet, media) │ └── globals.css # Tailwind 4 configuration & global styles ├── components/ # UI Components -│ ├── [tool]/ # Tool-specific components (e.g., components/pastel/) +│ ├── [tool]/ # Tool-specific components (e.g., components/color/) │ ├── layout/ # AppShell, Sidebar, Header │ └── ui/ # Base Atomic Components (shadcn) ├── lib/ # Business Logic diff --git a/README.md b/README.md index a8e3f70..42eef40 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Built with **Next.js 16**, **React 19**, and **Tailwind CSS 4**, Kit UI delivers Kit UI is divided into four core specialized applications: -### 🎨 [Pastel](./app/(app)/pastel) — Professional Color Toolkit +### 🎨 [Color](./app/(app)/color) — Professional Color Toolkit A comprehensive suite for color theory, manipulation, and accessibility. - **Color Playground**: Interactive HSL/RGB/HEX manipulation with real-time analysis. - **Accessibility Suite**: WCAG 2.1 Contrast Checker and a real-time Colorblindness Simulator. @@ -73,16 +73,16 @@ Privacy-first, local-only media conversion powered by WebAssembly. ```bash . ├── app/ # Next.js App Router (Pages & Layouts) -│ ├── (app)/ # Core Tool Pages (Pastel, Units, Figlet, Media) +│ ├── (app)/ # Core Tool Pages (Color, Units, Figlet, Media) │ └── api/ # Backend API routes ├── components/ # Reusable UI & Logic Components -│ ├── pastel/ # Color-specific components +│ ├── color/ # Color-specific components │ ├── units/ # Converter-specific components │ ├── figlet/ # ASCII-specific components │ ├── media/ # Media conversion components │ └── ui/ # Base Atomic Components (Buttons, Cards, etc.) ├── lib/ # Business Logic & Utilities -│ ├── pastel/ # WASM wrappers & Color logic +│ ├── color/ # WASM wrappers & Color logic │ ├── units/ # Conversion algorithms │ ├── figlet/ # Font loading & ASCII generation │ └── media/ # FFmpeg & ImageMagick WASM orchestration @@ -130,7 +130,7 @@ docker run -p 80:80 kit-ui ## 📈 Performance & Optimization - **Static Site Generation (SSG)**: Entire toolkit is exported as static HTML/JS for sub-second load times. -- **Client-Side WASM**: Complex processing (FFmpeg, ImageMagick, Pastel) is offloaded to WebAssembly for native-level performance without server latency. +- **Client-Side WASM**: Complex processing (FFmpeg, ImageMagick, Color) is offloaded to WebAssembly for native-level performance without server latency. - **CSS-First Configuration**: Leveraging Tailwind 4's native CSS variables for zero-runtime styling overhead. - **Automatic CI/CD**: GitHub Actions pipeline for multi-architecture Docker builds. diff --git a/app/(app)/pastel/globals.css b/app/(app)/color/globals.css similarity index 93% rename from app/(app)/pastel/globals.css rename to app/(app)/color/globals.css index 1a4caac..6184809 100644 --- a/app/(app)/pastel/globals.css +++ b/app/(app)/color/globals.css @@ -4,16 +4,7 @@ @source "../components/color/*.{js,ts,jsx,tsx}"; @source "../components/layout/*.{js,ts,jsx,tsx}"; @source "../components/providers/*.{js,ts,jsx,tsx}"; -@source "../components/tools/*.{js,ts,jsx,tsx}"; @source "../components/ui/*.{js,ts,jsx,tsx}"; -@source "./distinct/*.{js,ts,jsx,tsx}"; -@source "./gradient/*.{js,ts,jsx,tsx}"; -@source "./harmony/*.{js,ts,jsx,tsx}"; -@source "./names/*.{js,ts,jsx,tsx}"; -@source "./batch/*.{js,ts,jsx,tsx}"; -@source "./colorblind/*.{js,ts,jsx,tsx}"; -@source "./contrast/*.{js,ts,jsx,tsx}"; -@source "./textcolor/*.{js,ts,jsx,tsx}"; @source "*.{js,ts,jsx,tsx}"; @custom-variant dark (&:is(.dark *)); diff --git a/app/(app)/pastel/layout.tsx b/app/(app)/color/layout.tsx similarity index 74% rename from app/(app)/pastel/layout.tsx rename to app/(app)/color/layout.tsx index ba481ed..7980490 100644 --- a/app/(app)/pastel/layout.tsx +++ b/app/(app)/color/layout.tsx @@ -1,4 +1,4 @@ -export default function PastelLayout({ +export default function ColorLayout({ children, }: Readonly<{ children: React.ReactNode; diff --git a/app/(app)/pastel/page.tsx b/app/(app)/color/page.tsx similarity index 96% rename from app/(app)/pastel/page.tsx rename to app/(app)/color/page.tsx index ade8cca..51e2ac9 100644 --- a/app/(app)/pastel/page.tsx +++ b/app/(app)/color/page.tsx @@ -2,14 +2,14 @@ import { useState, useEffect, Suspense } from 'react'; import { useSearchParams, useRouter } from 'next/navigation'; -import { ColorPicker } from '@/components/pastel/ColorPicker'; -import { ColorInfo } from '@/components/pastel/ColorInfo'; -import { ManipulationPanel } from '@/components/pastel/ManipulationPanel'; -import { PaletteGrid } from '@/components/pastel/PaletteGrid'; -import { ExportMenu } from '@/components/pastel/ExportMenu'; +import { ColorPicker } from '@/components/color/ColorPicker'; +import { ColorInfo } from '@/components/color/ColorInfo'; +import { ManipulationPanel } from '@/components/color/ManipulationPanel'; +import { PaletteGrid } from '@/components/color/PaletteGrid'; +import { ExportMenu } from '@/components/color/ExportMenu'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { AppPage } from '@/components/layout/AppPage'; -import { useColorInfo, useGeneratePalette, useGenerateGradient } from '@/lib/pastel/api/queries'; +import { useColorInfo, useGeneratePalette, useGenerateGradient } from '@/lib/color/api/queries'; import { Loader2, Share2, Palette, Plus, X, Layers } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; @@ -59,7 +59,7 @@ function PlaygroundContent() { useEffect(() => { const hex = color.replace('#', ''); if (hex.length === 6 || hex.length === 3) { - router.push(`/pastel?color=${hex}`, { scroll: false }); + router.push(`/color?color=${hex}`, { scroll: false }); } }, [color, router]); @@ -72,7 +72,7 @@ function PlaygroundContent() { // Share color via URL const handleShare = () => { - const url = `${window.location.origin}/pastel?color=${color.replace('#', '')}`; + const url = `${window.location.origin}/color?color=${color.replace('#', '')}`; navigator.clipboard.writeText(url); toast.success('Link copied to clipboard!'); }; @@ -134,7 +134,7 @@ function PlaygroundContent() { return (
diff --git a/app/layout.tsx b/app/layout.tsx index 5a4a4a7..80c2999 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -7,7 +7,7 @@ const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000'; export const metadata: Metadata = { title: 'Kit - Your Creative Toolkit', description: 'A curated collection of creative and utility tools for developers and creators. Features file conversion, image editing, and color manipulation.', - keywords: ['tools', 'utilities', 'file converter', 'image editor', 'color palette', 'creative toolkit', 'convert', 'paint', 'pastel', 'open source'], + keywords: ['tools', 'utilities', 'file converter', 'image editor', 'color palette', 'creative toolkit', 'convert', 'paint', 'color', 'open source'], metadataBase: new URL(siteUrl), icons: { icon: '/icon.png', diff --git a/components/AppIcons.tsx b/components/AppIcons.tsx index 6be0f17..6e7b56e 100644 --- a/components/AppIcons.tsx +++ b/components/AppIcons.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -export const PastelIcon = (props: React.SVGProps) => ( +export const ColorIcon = (props: React.SVGProps) => ( diff --git a/components/ToolsGrid.tsx b/components/ToolsGrid.tsx index 539267f..fb4c113 100644 --- a/components/ToolsGrid.tsx +++ b/components/ToolsGrid.tsx @@ -2,17 +2,17 @@ import { motion } from 'framer-motion'; import ToolCard from './ToolCard'; -import { PastelIcon, UnitsIcon, FigletIcon, MediaIcon } from '@/components/AppIcons'; +import { ColorIcon, UnitsIcon, FigletIcon, MediaIcon } from '@/components/AppIcons'; const tools = [ { - title: 'Pastel', + title: 'Color', description: 'Modern color manipulation toolkit with palette generation, accessibility testing, and format conversion. Supports hex, RGB, HSL, Lab, and more.', - url: '/pastel', + url: '/color', gradient: 'gradient-indigo-purple', accentColor: '#a855f7', badges: ['Open Source', 'WCAG', 'Free'], - icon: , + icon: , }, { title: 'Units', diff --git a/components/pastel/ColorDisplay.tsx b/components/color/ColorDisplay.tsx similarity index 100% rename from components/pastel/ColorDisplay.tsx rename to components/color/ColorDisplay.tsx diff --git a/components/pastel/ColorInfo.tsx b/components/color/ColorInfo.tsx similarity index 98% rename from components/pastel/ColorInfo.tsx rename to components/color/ColorInfo.tsx index a6a09aa..97ab842 100644 --- a/components/pastel/ColorInfo.tsx +++ b/components/color/ColorInfo.tsx @@ -1,6 +1,6 @@ 'use client'; -import { ColorInfo as ColorInfoType } from '@/lib/pastel/api/types'; +import { ColorInfo as ColorInfoType } from '@/lib/color/api/types'; import { Button } from '@/components/ui/button'; import { Copy } from 'lucide-react'; import { toast } from 'sonner'; diff --git a/components/pastel/ColorPicker.tsx b/components/color/ColorPicker.tsx similarity index 97% rename from components/pastel/ColorPicker.tsx rename to components/color/ColorPicker.tsx index 18d7a63..94a123a 100644 --- a/components/pastel/ColorPicker.tsx +++ b/components/color/ColorPicker.tsx @@ -3,7 +3,7 @@ import { HexColorPicker } from 'react-colorful'; import { Input } from '@/components/ui/input'; import { cn } from '@/lib/utils/cn'; -import { hexToRgb } from '@/lib/pastel/utils/color'; +import { hexToRgb } from '@/lib/color/utils/color'; interface ColorPickerProps { color: string; diff --git a/components/pastel/ColorSwatch.tsx b/components/color/ColorSwatch.tsx similarity index 100% rename from components/pastel/ColorSwatch.tsx rename to components/color/ColorSwatch.tsx diff --git a/components/pastel/ExportMenu.tsx b/components/color/ExportMenu.tsx similarity index 97% rename from components/pastel/ExportMenu.tsx rename to components/color/ExportMenu.tsx index e24b0c4..000f043 100644 --- a/components/pastel/ExportMenu.tsx +++ b/components/color/ExportMenu.tsx @@ -19,8 +19,8 @@ import { exportAsJavaScript, downloadAsFile, type ExportColor, -} from '@/lib/pastel/utils/export'; -import { pastelAPI } from '@/lib/pastel/api/client'; +} from '@/lib/color/utils/export'; +import { colorAPI } from '@/lib/color/api/client'; interface ExportMenuProps { colors: string[]; @@ -46,7 +46,7 @@ export function ExportMenu({ colors, className }: ExportMenuProps) { setIsConverting(true); try { - const response = await pastelAPI.convertFormat({ + const response = await colorAPI.convertFormat({ colors, format: colorSpace, }); diff --git a/components/pastel/ManipulationPanel.tsx b/components/color/ManipulationPanel.tsx similarity index 99% rename from components/pastel/ManipulationPanel.tsx rename to components/color/ManipulationPanel.tsx index fd3f39c..f173ba8 100644 --- a/components/pastel/ManipulationPanel.tsx +++ b/components/color/ManipulationPanel.tsx @@ -10,7 +10,7 @@ import { useDesaturate, useRotate, useComplement -} from '@/lib/pastel/api/queries'; +} from '@/lib/color/api/queries'; import { toast } from 'sonner'; interface ManipulationPanelProps { diff --git a/components/pastel/PaletteGrid.tsx b/components/color/PaletteGrid.tsx similarity index 100% rename from components/pastel/PaletteGrid.tsx rename to components/color/PaletteGrid.tsx diff --git a/components/layout/AppSidebar.tsx b/components/layout/AppSidebar.tsx index 025071c..06e7d2e 100644 --- a/components/layout/AppSidebar.tsx +++ b/components/layout/AppSidebar.tsx @@ -17,7 +17,7 @@ import { cn } from '@/lib/utils/cn'; import Logo from '@/components/Logo'; import { useSidebar } from './SidebarProvider'; import { Button } from '@/components/ui/button'; -import { PastelIcon, UnitsIcon, FigletIcon, MediaIcon } from '@/components/AppIcons'; +import { ColorIcon, UnitsIcon, FigletIcon, MediaIcon } from '@/components/AppIcons'; interface NavItem { title: string; @@ -46,9 +46,9 @@ const navigation: NavGroup[] = [ icon: }, { - title: 'Pastel', - href: '/pastel', - icon: + title: 'Color Manipulation', + href: '/color', + icon: }, { title: 'Media Converter', diff --git a/lib/pastel/api/client.ts b/lib/color/api/client.ts similarity index 96% rename from lib/pastel/api/client.ts rename to lib/color/api/client.ts index 34ca1bc..d67a2f2 100644 --- a/lib/pastel/api/client.ts +++ b/lib/color/api/client.ts @@ -15,15 +15,15 @@ import type { PaletteGenerateRequest, PaletteGenerateData, } from './types'; -import { pastelWASM } from './wasm-client'; +import { colorWASM } from './wasm-client'; -export class PastelAPIClient { +export class ColorAPIClient { private baseURL: string; constructor(baseURL?: string) { // Use the Next.js API proxy route for runtime configuration // This allows changing the backend API URL without rebuilding - this.baseURL = baseURL || '/api/pastel'; + this.baseURL = baseURL || '/api/color'; } private async request( @@ -172,4 +172,4 @@ export class PastelAPIClient { // Export singleton instance // Now using WASM client for zero-latency, offline-first color operations -export const pastelAPI = pastelWASM; +export const colorAPI = colorWASM; diff --git a/lib/pastel/api/queries.ts b/lib/color/api/queries.ts similarity index 83% rename from lib/pastel/api/queries.ts rename to lib/color/api/queries.ts index 99fc6ed..03ceb8c 100644 --- a/lib/pastel/api/queries.ts +++ b/lib/color/api/queries.ts @@ -1,7 +1,7 @@ 'use client'; import { useQuery, useMutation, UseQueryOptions } from '@tanstack/react-query'; -import { pastelAPI } from './client'; +import { colorAPI } from './client'; import { ColorInfoRequest, ColorInfoData, @@ -26,7 +26,7 @@ export const useColorInfo = ( return useQuery({ queryKey: ['colorInfo', request.colors], queryFn: async () => { - const response = await pastelAPI.getColorInfo(request); + const response = await colorAPI.getColorInfo(request); if (!response.success) { throw new Error(response.error.message); } @@ -41,7 +41,7 @@ export const useColorInfo = ( export const useConvertFormat = () => { return useMutation({ mutationFn: async (request: ConvertFormatRequest) => { - const response = await pastelAPI.convertFormat(request); + const response = await colorAPI.convertFormat(request); if (!response.success) { throw new Error(response.error.message); } @@ -54,7 +54,7 @@ export const useConvertFormat = () => { export const useLighten = () => { return useMutation({ mutationFn: async (request: ColorManipulationRequest) => { - const response = await pastelAPI.lighten(request); + const response = await colorAPI.lighten(request); if (!response.success) { throw new Error(response.error.message); } @@ -66,7 +66,7 @@ export const useLighten = () => { export const useDarken = () => { return useMutation({ mutationFn: async (request: ColorManipulationRequest) => { - const response = await pastelAPI.darken(request); + const response = await colorAPI.darken(request); if (!response.success) { throw new Error(response.error.message); } @@ -78,7 +78,7 @@ export const useDarken = () => { export const useSaturate = () => { return useMutation({ mutationFn: async (request: ColorManipulationRequest) => { - const response = await pastelAPI.saturate(request); + const response = await colorAPI.saturate(request); if (!response.success) { throw new Error(response.error.message); } @@ -90,7 +90,7 @@ export const useSaturate = () => { export const useDesaturate = () => { return useMutation({ mutationFn: async (request: ColorManipulationRequest) => { - const response = await pastelAPI.desaturate(request); + const response = await colorAPI.desaturate(request); if (!response.success) { throw new Error(response.error.message); } @@ -102,7 +102,7 @@ export const useDesaturate = () => { export const useRotate = () => { return useMutation({ mutationFn: async (request: ColorManipulationRequest) => { - const response = await pastelAPI.rotate(request); + const response = await colorAPI.rotate(request); if (!response.success) { throw new Error(response.error.message); } @@ -114,7 +114,7 @@ export const useRotate = () => { export const useComplement = () => { return useMutation({ mutationFn: async (colors: string[]) => { - const response = await pastelAPI.complement(colors); + const response = await colorAPI.complement(colors); if (!response.success) { throw new Error(response.error.message); } @@ -127,7 +127,7 @@ export const useComplement = () => { export const useGenerateRandom = () => { return useMutation({ mutationFn: async (request: RandomColorsRequest) => { - const response = await pastelAPI.generateRandom(request); + const response = await colorAPI.generateRandom(request); if (!response.success) { throw new Error(response.error.message); } @@ -139,7 +139,7 @@ export const useGenerateRandom = () => { export const useGenerateGradient = () => { return useMutation({ mutationFn: async (request: GradientRequest) => { - const response = await pastelAPI.generateGradient(request); + const response = await colorAPI.generateGradient(request); if (!response.success) { throw new Error(response.error.message); } @@ -153,7 +153,7 @@ export const useHealth = () => { return useQuery({ queryKey: ['health'], queryFn: async () => { - const response = await pastelAPI.getHealth(); + const response = await colorAPI.getHealth(); if (!response.success) { throw new Error(response.error.message); } @@ -167,7 +167,7 @@ export const useHealth = () => { export const useGeneratePalette = () => { return useMutation({ mutationFn: async (request: PaletteGenerateRequest) => { - const response = await pastelAPI.generatePalette(request); + const response = await colorAPI.generatePalette(request); if (!response.success) { throw new Error(response.error.message); } diff --git a/lib/pastel/api/types.ts b/lib/color/api/types.ts similarity index 100% rename from lib/pastel/api/types.ts rename to lib/color/api/types.ts diff --git a/lib/pastel/api/wasm-client.ts b/lib/color/api/wasm-client.ts similarity index 98% rename from lib/pastel/api/wasm-client.ts rename to lib/color/api/wasm-client.ts index d136595..f824889 100644 --- a/lib/pastel/api/wasm-client.ts +++ b/lib/color/api/wasm-client.ts @@ -41,11 +41,11 @@ async function ensureWasmInit() { } /** - * WASM-based Pastel client - * Provides the same interface as PastelAPIClient but uses WebAssembly + * WASM-based Color client + * Provides the same interface as ColorAPIClient but uses WebAssembly * Zero network latency, works offline! */ -export class PastelWASMClient { +export class ColorWASMClient { constructor() { // Initialize WASM eagerly ensureWasmInit().catch(console.error); @@ -347,4 +347,4 @@ export class PastelWASMClient { } // Export singleton instance -export const pastelWASM = new PastelWASMClient(); +export const colorWASM = new ColorWASMClient(); diff --git a/lib/pastel/index.ts b/lib/color/index.ts similarity index 100% rename from lib/pastel/index.ts rename to lib/color/index.ts diff --git a/lib/pastel/utils/color.ts b/lib/color/utils/color.ts similarity index 100% rename from lib/pastel/utils/color.ts rename to lib/color/utils/color.ts diff --git a/lib/pastel/utils/export.ts b/lib/color/utils/export.ts similarity index 100% rename from lib/pastel/utils/export.ts rename to lib/color/utils/export.ts