diff --git a/.claude/skills/code-gen.md b/.claude/skills/code-gen.md index 89a0cfc..c457925 100644 --- a/.claude/skills/code-gen.md +++ b/.claude/skills/code-gen.md @@ -12,9 +12,106 @@ Du bist ein Code-Generator für React + Node.js Webprojekte. - Props-Interface immer definieren - Error Boundaries für kritische Komponenten - Loading/Error States berücksichtigen -- Responsive Design (Mobile-First) +- **Mobile-First Responsive Design** (siehe unten) +- **Dark Mode immer einbauen** (siehe unten) - Styling: Tailwind CSS oder CSS Modules +### Mobile-First Pflicht +Jede Komponente wird zuerst für Mobile designt, dann für größere Screens erweitert: +- Tailwind: Basis-Klassen = Mobile, `sm:`, `md:`, `lg:` für größere Screens +- Touch-freundliche Elemente: min. 44x44px Tap-Targets +- Hamburger-Menu / Drawer-Navigation auf Mobile +- Flexible Grids: `grid-cols-1` auf Mobile, `sm:grid-cols-2`, `lg:grid-cols-3` +- Bilder/Medien: `max-w-full`, Lazy Loading +- Formulare: Vollbreite Inputs auf Mobile, mehrspaltig ab `md:` +- Testen: Layout muss ab 320px Breite funktionieren + +### Dark Mode Pflicht +Jede Komponente muss Dark Mode unterstützen. Implementierung: + +#### Theme-Provider (einmalig im Projekt) +```typescript +// src/hooks/useTheme.ts +import { useState, useEffect, createContext, useContext } from 'react'; + +type Theme = 'light' | 'dark' | 'system'; + +const ThemeContext = createContext<{ + theme: Theme; + resolvedTheme: 'light' | 'dark'; + setTheme: (theme: Theme) => void; +}>({ theme: 'system', resolvedTheme: 'light', setTheme: () => {} }); + +export function ThemeProvider({ children }: { children: React.ReactNode }) { + const [theme, setTheme] = useState(() => { + return (localStorage.getItem('theme') as Theme) || 'system'; + }); + + const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>('light'); + + useEffect(() => { + const root = document.documentElement; + const systemDark = window.matchMedia('(prefers-color-scheme: dark)'); + + const apply = () => { + const isDark = theme === 'dark' || (theme === 'system' && systemDark.matches); + root.classList.toggle('dark', isDark); + setResolvedTheme(isDark ? 'dark' : 'light'); + }; + + apply(); + localStorage.setItem('theme', theme); + systemDark.addEventListener('change', apply); + return () => systemDark.removeEventListener('change', apply); + }, [theme]); + + return ( + + {children} + + ); +} + +export const useTheme = () => useContext(ThemeContext); +``` + +#### Theme-Toggle Komponente +```typescript +// src/components/ThemeToggle.tsx +import { useTheme } from '../hooks/useTheme'; + +export function ThemeToggle() { + const { theme, setTheme } = useTheme(); + const next = { light: 'dark', dark: 'system', system: 'light' } as const; + return ( + + ); +} +``` + +#### Tailwind Dark Mode Config +```javascript +// tailwind.config.js +module.exports = { + darkMode: 'class', + // ... +} +``` + +#### Styling-Regeln für Dark Mode +- Immer `dark:` Variante angeben: `bg-white dark:bg-gray-900` +- Text: `text-gray-900 dark:text-gray-100` +- Borders: `border-gray-200 dark:border-gray-700` +- Inputs: `bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100` +- Hover: `hover:bg-gray-100 dark:hover:bg-gray-800` +- Keine hardcoded Farben ohne `dark:` Gegenstück + ## BACKEND-REGELN (Node.js/Express) - Express mit TypeScript - Controller/Service/Repository Pattern @@ -29,7 +126,7 @@ Frontend: ``` src/ components/ # React-Komponenten - hooks/ # Custom Hooks + hooks/ # Custom Hooks (inkl. useTheme) services/ # API-Calls types/ # TypeScript Interfaces utils/ # Hilfsfunktionen @@ -54,3 +151,4 @@ src/ - DRY-Prinzip - SOLID-Prinzipien - Jede Komponente/Service in eigener Datei +- **Jede UI-Komponente: Mobile-First + Dark Mode**