# CLAUDE.md — Portfolio johanleroy.fr Site vitrine personnel en **Astro 6 hybrid** (SSG public + SSR admin), identité **Cyberpunk Dark / Free Party tekno**. ## Contexte rapide - Utilisateur : **Johan Leroy** — dev fullstack + DJ tekno - Objectif : remplacer l'ancien portfolio Angular 19 (`~/WebstormProjects/Portfolio_angular/`) par une version moderne, animée, maintenable sans recompilation - Déploiement : **Plesk Node.js** sur `johanleroy.fr` (CI Gitea FTP) - Commande `/context johanleroy` charge tout le contexte projet ## Stack - **Astro 6** hybrid (`output: 'static'` + `@astrojs/node` standalone) - **React 19** (îlots interactifs uniquement) - **Tailwind CSS 4** + design system custom - **Framer Motion** + **Lenis** (animations) - **Zod** (schémas de contenu) - **jose + bcryptjs** (auth admin) - **@iconify-icon/react** (icônes simple-icons + lucide) ## Points critiques à connaître ### Content Tout le contenu du site est dans `public/content/*.json` (7 fichiers). Chaque fichier est validé par un schéma Zod dans `src/content/schemas/`. Édition possible via `/admin` ou directement en éditant le JSON. ### Admin Protégé par mot de passe bcrypt + JWT cookie httpOnly 7j. Middleware dans `src/middleware.ts`. Routes `/admin/*` et `/api/*` ont `export const prerender = false`. ### Env vars (.env) ``` ADMIN_PASSWORD_HASH=$2b$12$... ADMIN_JWT_SECRET=... PORT=3100 ``` Générer : `npm run hash:password -- 'monMotDePasse'` (⚠️ **guillemets simples** toujours — les `!` et `$` sont interprétés par bash sinon). Important : `src/lib/auth.ts` lit à la fois `import.meta.env` (dev Vite) ET `process.env` (prod Node standalone). Ne pas casser ce merge. ### Design - **Palette** : `--color-bg #0A0A0F`, `--color-cyan #00F0FF`, `--color-acid #C6FF00`, `--color-magenta #FF2A6D`, `--color-red #FF0040` - **Typos** : Inter (body), Space Grotesk (display), JetBrains Mono (code), **Bebas Neue** (stencil signature) - **Dark only** — pas de light mode - **Ligne éditoriale** : pro avant tout (nav FR, URLs grand public), free party = déco (stickers, BPM, LED, stencil) ### Animations Tous les composants animés **doivent** respecter `prefers-reduced-motion`. Les 14 blocs livrés sont listés dans la memory `animations-blocks.md`. ### Feedback important - ❌ Pas de 3D Hero pour l'instant (supprimé — on y reviendra) - ❌ Pas de curseur custom (supprimé) - ✅ Nav FR standards (`/projets`, `/experience`, `/formations`) - ✅ Sons off par défaut, togglables via header - ✅ Boot sequence au 1er load uniquement (sessionStorage) - ✅ Responsive : fallback grid pour le Crate horizontal pinned sur mobile ## Commandes utiles - `npm run dev` — port 3100 - `npm run build` — check + build prod - `npm run check` — `astro check` - `npm run hash:password -- 'mdp'` — génère bcrypt + JWT secret ## Conventions de code - Tous les îlots React dans `src/components/islands/` - Composants Astro pure (sans JS) directement dans `src/components/` - Les schémas Zod sont la source de vérité pour les types — **ne pas** écrire de type custom à la main pour le contenu - `astro check` doit passer à 0 erreur avant commit - Utiliser `className` en TSX et `class` en Astro (erreur Astro commune) ## Workflow d'édition 1. Lire `docs/README.md` puis `docs/01-analyse-et-plan.md` + `docs/02-moodboard-freeparty.md` pour la direction artistique 2. Pour un changement de contenu → éditer `public/content/*.json` (ou via `/admin`) 3. Pour un changement de design → modifier `src/styles/global.css` + composants 4. Pour un changement structurel → modifier schéma Zod d'abord, puis composant, puis JSON ## Ne PAS faire sans demander - Ne pas changer la stack (Astro + React + Tailwind 4 est verrouillé) - Ne pas réintroduire de 3D hero sans validation - Ne pas retirer le respect `prefers-reduced-motion` - Ne pas commiter `.env` (vérifier `.gitignore`) - Ne pas toucher à `dist/` (généré par build)