diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..29b9d1f --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "semi": true, + "trailingComma": "es5", + "singleQuote": true, + "printWidth": 100, + "tabWidth": 2, + "useTabs": false +} diff --git a/app/globals.css b/app/globals.css new file mode 100644 index 0000000..10c2d37 --- /dev/null +++ b/app/globals.css @@ -0,0 +1,59 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 222.2 84% 4.9%; + --radius: 0.5rem; + } + + .dark { + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + --primary: 210 40% 98%; + --primary-foreground: 222.2 47.4% 11.2%; + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + --accent: 217.2 32.6% 17.5%; + --accent-foreground: 210 40% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 40% 98%; + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + --ring: 212.7 26.8% 83.9%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/app/layout.tsx b/app/layout.tsx new file mode 100644 index 0000000..9fc34b3 --- /dev/null +++ b/app/layout.tsx @@ -0,0 +1,26 @@ +import type { Metadata } from 'next'; +import { Inter } from 'next/font/google'; +import './globals.css'; +import { Providers } from '@/components/providers/Providers'; + +const inter = Inter({ subsets: ['latin'] }); + +export const metadata: Metadata = { + title: 'Pastel UI - Color Manipulation & Palette Generation', + description: 'Modern web UI for color manipulation, palette generation, and accessibility analysis', + keywords: ['color', 'palette', 'generator', 'accessibility', 'wcag', 'gradient', 'design'], +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + {children} + + + ); +} diff --git a/app/page.tsx b/app/page.tsx new file mode 100644 index 0000000..a61c367 --- /dev/null +++ b/app/page.tsx @@ -0,0 +1,48 @@ +export default function Home() { + return ( +
+
+

+ Pastel UI +

+

+ Modern web UI for color manipulation, palette generation, and accessibility analysis +

+
+ + Open Playground + + + Generate Palettes + +
+
+
+

Color Playground

+

+ Interactive color picker with multi-format support and real-time manipulation +

+
+
+

Palette Generation

+

+ Create harmony palettes, distinct colors, and smooth gradients +

+
+
+

Accessibility Tools

+

+ WCAG contrast checker and color blindness simulation +

+
+
+
+
+ ); +} diff --git a/components/providers/Providers.tsx b/components/providers/Providers.tsx new file mode 100644 index 0000000..bf9d998 --- /dev/null +++ b/components/providers/Providers.tsx @@ -0,0 +1,26 @@ +'use client'; + +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { Toaster } from 'sonner'; +import { useState } from 'react'; + +export function Providers({ children }: { children: React.ReactNode }) { + const [queryClient] = useState( + () => + new QueryClient({ + defaultOptions: { + queries: { + staleTime: 60 * 1000, // 1 minute + refetchOnWindowFocus: false, + }, + }, + }) + ); + + return ( + + {children} + + + ); +} diff --git a/components/ui/button.tsx b/components/ui/button.tsx new file mode 100644 index 0000000..eb82511 --- /dev/null +++ b/components/ui/button.tsx @@ -0,0 +1,40 @@ +import * as React from 'react'; +import { cn } from '@/lib/utils/cn'; + +export interface ButtonProps extends React.ButtonHTMLAttributes { + variant?: 'default' | 'outline' | 'ghost' | 'destructive'; + size?: 'default' | 'sm' | 'lg' | 'icon'; +} + +const Button = React.forwardRef( + ({ className, variant = 'default', size = 'default', ...props }, ref) => { + return ( +