feat(epic-4): chemins narratifs, easter eggs, challenge et contact

Epic 4: Chemins Narratifs, Challenge & Contact

Stories implementees:
- 4.1: Composant ChoiceCards pour choix narratifs binaires
- 4.2: Sequence d'intro narrative avec Le Bug
- 4.3: Chemins narratifs differencies avec useNarrativePath
- 4.4: Table easter_eggs et systeme de detection (API + composable)
- 4.5: Easter eggs UI (popup, notification, collection)
- 4.6: Page challenge avec puzzle de code
- 4.7: Page revelation "Monde de Code"
- 4.8: Page contact avec formulaire et stats

Fichiers crees:
- Frontend: ChoiceCards, IntroSequence, ZoneEndChoice, EasterEggPopup,
  CodePuzzle, ChallengeSuccess, CodeWorld, et pages intro/challenge/revelation
- API: EasterEggController, Model, Migration, Seeder

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-08 13:35:12 +01:00
parent 64b1a33d10
commit 7e87a341a2
38 changed files with 3037 additions and 96 deletions

View File

@@ -179,6 +179,16 @@
"clickToSkip": "Cliquez ou appuyez sur Espace pour passer",
"bugAlt": "Le Bug - Stade {stage}"
},
"intro": {
"continue": "Continuer",
"startExploring": "Commencer l'exploration",
"skip": "Passer l'intro",
"fallback": {
"seq1": "Bienvenue dans mon domaine... Je suis Le Bug, ton guide pour cette aventure.",
"seq2": "Il y a quelqu'un ici que tu cherches... Un développeur mystérieux qui a créé tout ce que tu vois.",
"seq3": "Pour le trouver, explore ce monde. Chaque zone cache une partie de son histoire. Es-tu prêt ?"
}
},
"map": {
"ariaLabel": "Carte interactive du portfolio. Utilisez Tab pour naviguer entre les zones et Entrée pour explorer.",
"instructions": "Utilisez les touches Tab pour naviguer entre les zones et Entrée ou Espace pour explorer une zone.",
@@ -252,5 +262,63 @@
"title": "Résumé Express",
"description": "L'essentiel en un coup d'œil"
}
},
"easterEgg": {
"found": "Easter Egg trouve !",
"count": "{found} / {total} decouverts",
"difficulty": "Difficulte",
"collection": "Ma Collection",
"allFound": "Collection complete ! Tu es un vrai explorateur !",
"hint": "Continue d'explorer... des surprises sont cachees partout !"
},
"challenge": {
"title": "Une derniere epreuve...",
"intro": "Avant de rencontrer le developpeur, prouve que tu maitrises les bases du code. Rien de bien mechant, promis.",
"accept": "Relever le defi",
"skip": "Passer directement au contact",
"puzzleTitle": "Remets le code dans l'ordre",
"puzzleInstruction": "Glisse les lignes pour reconstituer la fonction qui debloque l'acces au developpeur.",
"hint1": "La fonction commence par function unlockDeveloper() {",
"hint2": "La variable secret est definie juste apres l'accolade ouvrante",
"hint3": "La derniere ligne avant l'accolade fermante est return Keep exploring...",
"hintLabel": "Indice",
"needHint": "Besoin d'aide ?",
"validate": "Verifier",
"validating": "Verification...",
"wrongOrder": "Ce n'est pas le bon ordre... Essaie encore !",
"moveUp": "Monter",
"moveDown": "Descendre",
"success": "Bravo !",
"successMessage": "Tu as prouve ta valeur. Le chemin vers le developpeur est maintenant ouvert...",
"redirecting": "Redirection en cours..."
},
"revelation": {
"loading": "Chargement...",
"bugSays": "Le Bug dit : Tu l'as trouve !",
"foundMe": "Tu m'as trouve !",
"message": "Bienvenue dans mon monde de code. Merci d'avoir explore tout ce chemin pour me trouver.",
"contactCta": "Me contacter",
"srDescription": "Page de revelation. Vous avez trouve le developpeur Celian. Un bouton permet de le contacter.",
"codeWorldAlt": "Un monde en ASCII art representant un paysage de code avec le message Tu m'as trouve au centre."
},
"contact": {
"statsTitle": "Ton parcours",
"zones": "Zones visitees",
"easterEggs": "Easter eggs",
"challenge": "Defi",
"title": "Me contacter",
"subtitle": "Felicitations pour avoir explore tout ce chemin ! Je serais ravi d'echanger avec toi.",
"name": "Nom",
"namePlaceholder": "Ton nom",
"email": "Email",
"emailPlaceholder": "ton.email(at)example.com",
"message": "Message",
"messagePlaceholder": "Qu'est-ce qui t'amene ?",
"send": "Envoyer",
"sending": "Envoi en cours...",
"success": "Message envoye !",
"successMessage": "Merci pour ton message. Je te repondrai dans les plus brefs delais.",
"error": "Une erreur s'est produite. Reessaie plus tard.",
"rateLimitError": "Trop de tentatives. Patiente un moment avant de reessayer."
}
}