feat: full feature buildout — streaming, i18n, mastery map, admin, jobs

Progressive lesson streaming via onSegment callback (fixes SSE for non-English
users — locale was shadowed in lesson-reader useEffect). Adds: BullMQ workers,
Redis stream buffer, token budget enforcement, Langfuse tracing, golden-eval
runner, Playwright e2e scaffolding, lesson depth/locale/preferences schema,
mastery map UI, admin panel (blueprints/users/reports/quality/misconceptions),
image queries, source citations, view transitions, reading animations, i18n
(next-intl), PDF export, surprise endpoint, and 402 passing unit tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-08 22:08:14 +02:00
parent 4e38b5a791
commit 5bf6013460
161 changed files with 27152 additions and 1161 deletions
+586
View File
@@ -0,0 +1,586 @@
{
"lesson": {
"ariaLesson": "Lesson",
"ariaProgress": "Lesson progress",
"reading": "Reading",
"segments": "{count, plural, one {# segment} other {# segments}}",
"segmentLocked": "Complete the previous checkpoint to continue.",
"checkpoint": {
"predict": "Predict",
"explain": "Explain",
"solve": "Solve",
"placeholder": "Write your answer here…",
"checking": "Checking…",
"submitted": "Submitted",
"confidenceLegend": "Before you submit — how sure are you?",
"notSure": "Not sure",
"thinkSo": "Think so",
"confident": "Confident",
"notSureAria": "Not sure about my answer",
"thinkSoAria": "I think my answer is right",
"confidentAria": "I am confident in my answer"
},
"print": "Export PDF",
"considering": "Considering…",
"empty": "This lesson has no segments yet. Check back shortly — content is still being prepared.",
"outline": {
"intro": "What you'll explore",
"preparing": "Generating your lesson…",
"streaming": "Writing your lesson…",
"streamingLabel": "Lesson content loading"
},
"tangent": {
"placeholder": "Curious about something?",
"ariaInput": "Curiosity question",
"ariaAsk": "Ask",
"considering": "Looking into it…"
},
"journeyProgress": "Lesson {current} of {total}",
"complete": {
"ariaLabel": "Lesson complete",
"heading": "Lesson complete.",
"saved": "Progress saved.",
"saving": "Saving…",
"markComplete": "Mark complete",
"nextLesson": "Next lesson →",
"deepen": "Go deeper →",
"journeyDone": "Journey complete.",
"journeyDoneNote": "You've finished all lessons in this journey."
}
},
"review": {
"title": "Daily Review",
"aria": "Daily review session",
"loading": "Loading your review…",
"empty": "Nothing due for review. Check back tomorrow.",
"progress": "{current} of {total}",
"considering": "Considering…",
"next": "Next →",
"finish": "Finish",
"complete": {
"heading": "Session complete",
"reviewed": "{count, plural, one {# concept reviewed} other {# concepts reviewed}}",
"netDelta": "Net mastery: {delta}",
"nothingDue": "You're all caught up.",
"backHome": "Back to learning"
},
"delta": {
"up": "↑ {pct}%",
"down": "↓ {pct}%",
"same": "unchanged"
},
"emptyUntil": "All caught up. Your next review is on {date}.",
"emptyNoHistory": "No reviews yet. Complete a lesson to start building your review queue."
},
"nav": {
"learn": "Learn",
"review": "Review",
"mastery": "Mastery",
"map": "Map",
"signIn": "Sign in",
"signOut": "Sign out",
"profile": "Profile",
"admin": "Admin"
},
"home": {
"eyebrow": "Curiosity-led mastery",
"title": "What do you want to understand?",
"lede": "Tell us what you're curious about.",
"fieldLabel": "Your learning intent",
"placeholder": "e.g. how vaccines work",
"examplesLabel": "Or try one of these",
"submit": "Start learning",
"submitting": "Finding your lesson…",
"error": "Something went wrong. Try again.",
"examples": [
"Why ice is slippery",
"How a gyroscope stays upright",
"Why the sky is blue",
"What temperature really is",
"How noise-cancelling headphones work",
"Why light speed is a limit",
"How lasers work",
"Why magnets attract",
"What causes friction",
"How a microwave heats food",
"Why glass is transparent",
"How superconductors work",
"What quantum entanglement is",
"Why mirrors flip left and right",
"How sound travels",
"What makes a rainbow",
"Why hot air rises",
"How a nuclear reactor works",
"What dark matter might be",
"Why time slows near light speed",
"How black holes form",
"Why the moon causes tides",
"What a neutron star is",
"How stars make elements",
"Why Mars is red",
"How rockets reach orbit",
"What the Big Bang was",
"Why Pluto isn't a planet",
"How GPS uses relativity",
"What causes solar eclipses",
"How telescopes see the past",
"Why galaxies spiral",
"What a light-year measures",
"How the sun produces energy",
"Why space is cold but sunlight burns",
"What causes the seasons",
"How comets get their tails",
"Why the universe is expanding",
"What exoplanets are",
"How auroras form",
"How vaccines work",
"Why onions make you cry",
"How memory is stored",
"Why we dream",
"How muscles grow",
"What causes aging",
"How antibiotics kill bacteria",
"Why we get fevers",
"How the immune system learns",
"What DNA actually does",
"How nerves send signals",
"Why we yawn",
"How the heart keeps rhythm",
"What gut bacteria do",
"How wounds heal",
"Why we need sleep",
"How eyes detect color",
"What causes allergies",
"How cells divide",
"Why exercise builds endurance",
"Why soap cleans",
"How batteries store energy",
"What makes something acidic",
"How glass is made",
"Why metals conduct electricity",
"How fireworks get their colors",
"What rust really is",
"How catalysts speed reactions",
"Why oil and water don't mix",
"How plastic is made",
"What pH measures",
"How fermentation works",
"Why diamonds are hard",
"How soap bubbles form",
"What makes chili peppers hot",
"How dry ice works",
"Why bread rises",
"How perfume spreads",
"What alloys are",
"How carbon dating works",
"TCP congestion control",
"How encryption keeps secrets",
"What a database index does",
"How neural networks learn",
"Why passwords get hashed",
"How the internet routes data",
"What a compiler does",
"How GPS finds your location",
"Why computers use binary",
"How a CPU executes code",
"What caching really solves",
"How Wi-Fi carries data",
"What blockchain actually is",
"How search engines rank pages",
"Why RAM is faster than disk",
"How image compression works",
"What an API is",
"How public-key crypto works",
"Why software has bugs",
"How machine translation works",
"Why prime numbers matter",
"What calculus measures",
"How probability works",
"Why pi is everywhere",
"What infinity really means",
"What a derivative tells you",
"Why zero was revolutionary",
"How statistics can mislead",
"What exponential growth means",
"Why some problems are unsolvable",
"How compound interest grows",
"What a logarithm is",
"Why the bell curve appears",
"How fractals are made",
"What Bayes' theorem does",
"Why we can't divide by zero",
"How GPS triangulates position",
"What a matrix represents",
"Why randomness is hard",
"How central banks set rates",
"What causes inflation",
"How stock markets work",
"Why money has value",
"What a recession is",
"How taxes shape behavior",
"Why prices rise and fall",
"What supply and demand means",
"How insurance spreads risk",
"Why trade benefits both sides",
"What GDP measures",
"How credit scores work",
"Why bubbles form and burst",
"How exchange rates move",
"Why monopolies are risky",
"What a bond is",
"How venture capital works",
"Why diversification matters",
"What game theory explains",
"How the printing press changed Europe",
"Why empires collapse",
"How writing was invented",
"What caused the Industrial Revolution",
"Why the Roman Empire fell",
"How money replaced barter",
"What sparked the Renaissance",
"How democracy began",
"Why the Silk Road mattered",
"What the Enlightenment changed",
"How plagues reshaped society",
"Why borders are where they are",
"How language families spread",
"What caused the Cold War",
"How cities first formed",
"Why revolutions happen",
"How navigation opened the world",
"What feudalism really was",
"How the calendar was set",
"Why some civilizations vanished",
"How earthquakes happen",
"Why volcanoes erupt",
"What causes weather",
"How mountains form",
"Why the ocean is salty",
"How rivers shape land",
"What drives ocean currents",
"Why deserts form where they do",
"How fossils are made",
"How clouds form rain",
"Why the climate is changing",
"How coral reefs grow",
"What plate tectonics explains",
"How caves form",
"Why leaves change color",
"How lightning forms",
"What soil is made of",
"How glaciers move",
"Why some places get monsoons",
"Why we procrastinate",
"How habits form",
"Why music moves us",
"How we learn languages",
"What makes things go viral",
"Why optical illusions fool us",
"How memory tricks work",
"Why we feel déjà vu",
"How persuasion works",
"What makes a melody catchy",
"Why crowds behave irrationally",
"How accents develop",
"Why we see faces everywhere",
"How the placebo effect works",
"Why deadlines boost focus",
"How color affects mood",
"Why stories stick with us",
"How bilingual brains switch",
"Why we forget names",
"How attention actually works"
],
"spark": "Spark something",
"sparking": "Finding something…",
"or": "or",
"depthLabel": "Lesson depth",
"depth": {
"quick": "Quick",
"quickMeta": "~5 min",
"standard": "Standard",
"standardMeta": "~10 min",
"deep": "Deep",
"deepMeta": "~20 min"
},
"modeLabel": "Format",
"mode": {
"practice": "Practice",
"read": "Just read"
},
"continue": {
"heading": "Continue learning",
"lessonProgress": "Lesson {position} of {total}",
"resume": "Resume →"
},
"dueReviews": "{count} due for review →"
},
"auth": {
"login": {
"title": "Sign in",
"email": "Email",
"password": "Password",
"submit": "Sign in",
"submitting": "Signing in…",
"error": "Invalid email or password.",
"forgotPassword": "Forgot password?",
"noAccount": "No account?",
"register": "Register",
"resetSuccess": "Password updated. Sign in with your new password.",
"or": "or",
"continueWithGoogle": "Continue with Google",
"continueWithGitHub": "Continue with GitHub",
"continueWith": "Continue with {provider}"
},
"register": {
"title": "Create account",
"name": "Name",
"email": "Email",
"password": "Password",
"confirmPassword": "Confirm password",
"passwordMismatch": "Passwords do not match.",
"submit": "Create account",
"submitting": "Creating account…",
"signInFailed": "Account created but sign-in failed. Try signing in manually.",
"hasAccount": "Already have an account?",
"signIn": "Sign in"
},
"forgotPassword": {
"title": "Reset password",
"email": "Email",
"submit": "Send reset link",
"submitting": "Sending…",
"sentTitle": "Check your inbox",
"sentBody": "If an account exists for that email, we sent a reset link. It expires in 1 hour.",
"backToSignIn": "Back to sign in",
"error": "Something went wrong. Try again."
},
"resetPassword": {
"title": "Set new password",
"newPassword": "New password",
"confirmPassword": "Confirm password",
"passwordMismatch": "Passwords do not match.",
"submit": "Set password",
"submitting": "Saving…",
"error": "Failed to reset password.",
"invalidLink": "Invalid reset link.",
"requestNew": "Request a new one"
},
"acceptInvite": {
"title": "Accept your invitation",
"subtitle": "Set up your account to get started.",
"email": "Email",
"name": "Your name",
"password": "Password",
"confirmPassword": "Confirm password",
"passwordMismatch": "Passwords do not match.",
"submit": "Create account",
"submitting": "Creating…",
"error": "Could not accept this invite.",
"invalidLink": "This invite link is invalid, expired, or already used.",
"goToLogin": "Go to sign in"
},
"verifyEmail": {
"title": "Verify your email",
"body": "We sent a verification link to your email address. Click it to activate your account.",
"subtext": "Didn't receive it? Check your spam folder."
},
"error": {
"title": "Authentication error",
"default": "Something went wrong during sign in.",
"Configuration": "Server configuration error. Contact support.",
"AccessDenied": "Access denied.",
"Verification": "The verification link has expired or already been used.",
"backToSignIn": "Back to sign in"
}
},
"settings": {
"title": "Settings",
"profile": {
"title": "Profile",
"name": "Display name",
"save": "Save",
"saving": "Saving…",
"saved": "Saved.",
"saveFailed": "Failed to save."
},
"language": {
"title": "Language",
"label": "Interface language",
"description": "Choose the language used throughout the app.",
"en": "English",
"fr": "Français"
},
"security": {
"title": "Security",
"currentPassword": "Current password",
"newPassword": "New password",
"confirmPassword": "Confirm new password",
"changePassword": "Change password",
"changing": "Changing…",
"changed": "Password changed.",
"failed": "Failed.",
"oauthNote": "Password change is not available for accounts using social sign-in.",
"linked": "Linked via: {providers}",
"passwordMismatch": "New passwords do not match."
},
"appearance": {
"title": "Appearance",
"theme": {
"label": "Theme",
"system": "System",
"light": "Light",
"dark": "Dark"
}
},
"danger": {
"title": "Danger zone",
"deleteAccount": "Delete account",
"deleteConfirm": "Delete my account",
"deleteWarning": "This will permanently delete your account and all your learning data. This cannot be undone.",
"deleting": "Deleting…"
},
"learning": {
"title": "Learning",
"description": "Shape how lessons are written for you.",
"ageGroup": {
"label": "Who is learning?",
"child": "Child (812)",
"teen": "Teen (1317)",
"adult": "Adult"
},
"difficulty": {
"label": "Default difficulty",
"1": "Beginner",
"2": "Intermediate",
"3": "Advanced"
},
"depth": {
"label": "Default lesson length",
"quick": "Quick (~5 min)",
"standard": "Standard (~10 min)",
"deep": "Deep (~20 min)"
},
"hint": {
"label": "About you (optional)",
"placeholder": "e.g. I'm a nurse, I like analogies with cooking…",
"description": "A short note helps tailor explanations to your background."
},
"save": "Save",
"saving": "Saving…",
"saved": "Saved.",
"saveFailed": "Failed to save."
},
"notifications": {
"title": "Notifications",
"description": "Control how Curio contacts you.",
"emailDigest": "Send me a daily email when reviews are due"
}
},
"onboarding": {
"title": "Welcome to Curio",
"subtitle": "Let's set up your learning profile. You can always change this later.",
"ageGroup": {
"label": "Who is learning?",
"child": "Child (812)",
"teen": "Teen (1317)",
"adult": "Adult"
},
"difficulty": {
"label": "How familiar are you with most topics?",
"1": "Beginner — build from first principles",
"2": "Intermediate — assume basic familiarity",
"3": "Advanced — go deep, explore edge cases"
},
"depth": {
"label": "Preferred lesson length",
"quick": "Quick (~5 min)",
"standard": "Standard (~10 min)",
"deep": "Deep (~20 min)"
},
"hint": {
"label": "Tell us a bit about yourself (optional)",
"placeholder": "e.g. I'm a nurse, I like analogies with cooking…",
"description": "Helps tailor explanations to your background."
},
"submit": "Get started",
"submitting": "Saving…",
"skip": "Skip for now"
},
"masteryMap": {
"title": "Mastery Map",
"loading": "Loading…",
"empty": "No mastery data yet.",
"emptyLink": "Start learning",
"due": "due",
"dueZone": {
"heading": "Due for review",
"startReview": "Start review →",
"none": "Nothing due right now."
},
"overview": {
"mastered": "Mastered",
"learning": "Learning",
"needsWork": "Needs work",
"progress": "{mastered} of {total} concepts mastered"
},
"status": {
"mastered": "Mastered",
"learning": "Learning",
"needsWork": "Needs work",
"notStarted": "Not started"
},
"filter": {
"all": "All",
"due": "Due",
"needsWork": "Needs work"
},
"remove": "Remove",
"removeBlueprint": "Remove {title} from mastery map"
},
"profile": {
"title": "Your profile",
"masteryTitle": "Mastery overview",
"noMastery": "No mastery data yet. Start learning to see progress here."
},
"grade": {
"verdict": {
"mastered": "Understood",
"partial": "Partial",
"misconception": "Misconception",
"uncertain": "Unclear"
},
"calibration": {
"confidentFailed": "You rated yourself confident — worth pausing on what tripped you.",
"unsurePassed": "You rated yourself unsure, but your answer was solid. Trust your understanding."
},
"referenceHeading": "Full answer",
"ariaFeedback": "Tutor feedback",
"ariaCalibration": "Calibration note",
"socratic": {
"ariaLabel": "Socratic follow-up",
"placeholder": "Go ahead…",
"ariaInput": "Follow-up answer",
"submit": "Reply",
"considering": "Considering…"
},
"reexplain": {
"loading": "Preparing another explanation…",
"trigger": "Try another explanation →"
},
"retry": "Try again →",
"report": {
"toggle": "Flag an issue",
"ariaLabel": "Report an issue",
"thanks": "Thanks — we'll look into it.",
"reasonGradeWrong": "Grade seems wrong",
"reasonContentError": "Content error",
"reasonOther": "Other",
"notesPlaceholder": "Optional details…",
"ariaReason": "Reason",
"ariaDetails": "Details",
"submit": "Send",
"cancel": "Cancel"
}
}
}
+586
View File
@@ -0,0 +1,586 @@
{
"lesson": {
"ariaLesson": "Leçon",
"ariaProgress": "Progression de la leçon",
"reading": "Lecture",
"segments": "{count, plural, one {# segment} other {# segments}}",
"segmentLocked": "Complétez le point de contrôle précédent pour continuer.",
"checkpoint": {
"predict": "Prédire",
"explain": "Expliquer",
"solve": "Résoudre",
"placeholder": "Écrivez votre réponse ici…",
"checking": "Analyse en cours…",
"submitted": "Envoyé",
"confidenceLegend": "Avant d'envoyer — à quel point êtes-vous sûr(e) ?",
"notSure": "Pas sûr(e)",
"thinkSo": "Je pense",
"confident": "Confiant(e)",
"notSureAria": "Je ne suis pas sûr(e) de ma réponse",
"thinkSoAria": "Je pense que ma réponse est correcte",
"confidentAria": "Je suis confiant(e) dans ma réponse"
},
"print": "Exporter PDF",
"considering": "En cours d'évaluation…",
"empty": "Cette leçon n'a pas encore de contenu. Revenez dans un instant — le contenu est en cours de préparation.",
"outline": {
"intro": "Ce que vous allez explorer",
"preparing": "Génération de votre leçon en cours…",
"streaming": "Rédaction de votre leçon…",
"streamingLabel": "Contenu de la leçon en chargement"
},
"tangent": {
"placeholder": "Quelque chose vous intrigue ?",
"ariaInput": "Question de curiosité",
"ariaAsk": "Envoyer",
"considering": "Je cherche…"
},
"journeyProgress": "Leçon {current} sur {total}",
"complete": {
"ariaLabel": "Leçon terminée",
"heading": "Leçon terminée.",
"saved": "Progression sauvegardée.",
"saving": "Sauvegarde…",
"markComplete": "Marquer comme terminé",
"nextLesson": "Leçon suivante →",
"deepen": "Approfondir →",
"journeyDone": "Parcours terminé.",
"journeyDoneNote": "Vous avez terminé toutes les leçons de ce parcours."
}
},
"review": {
"title": "Révision quotidienne",
"aria": "Session de révision quotidienne",
"loading": "Chargement de votre révision…",
"empty": "Rien à réviser pour l'instant. Revenez demain.",
"progress": "{current} sur {total}",
"considering": "En cours d'analyse…",
"next": "Suivant →",
"finish": "Terminer",
"complete": {
"heading": "Session terminée",
"reviewed": "{count, plural, one {# concept révisé} other {# concepts révisés}}",
"netDelta": "Maîtrise nette : {delta}",
"nothingDue": "Vous êtes à jour.",
"backHome": "Retour à l'apprentissage"
},
"delta": {
"up": "↑ {pct}%",
"down": "↓ {pct}%",
"same": "inchangé"
},
"emptyUntil": "Tout est à jour. Votre prochaine révision est le {date}.",
"emptyNoHistory": "Pas encore de révisions. Complétez une leçon pour commencer."
},
"nav": {
"learn": "Apprendre",
"review": "Révision",
"mastery": "Maîtrise",
"map": "Carte",
"signIn": "Se connecter",
"signOut": "Se déconnecter",
"profile": "Profil",
"admin": "Admin"
},
"home": {
"eyebrow": "Maîtrise guidée par la curiosité",
"title": "Qu'est-ce que vous voulez comprendre ?",
"lede": "Dites-nous ce qui vous intrigue.",
"fieldLabel": "Votre intention d'apprentissage",
"placeholder": "ex. comment fonctionnent les vaccins",
"examplesLabel": "Ou essayez l'un de ceux-ci",
"submit": "Commencer",
"submitting": "Recherche de votre leçon…",
"error": "Une erreur s'est produite. Réessayez.",
"examples": [
"Pourquoi la glace est glissante",
"Comment un gyroscope reste droit",
"Pourquoi le ciel est bleu",
"Ce qu'est vraiment la température",
"Comment fonctionne un casque à réduction de bruit",
"Pourquoi la vitesse de la lumière est une limite",
"Comment fonctionnent les lasers",
"Pourquoi les aimants attirent",
"Ce qui cause la friction",
"Comment un micro-ondes chauffe les aliments",
"Pourquoi le verre est transparent",
"Comment fonctionnent les supraconducteurs",
"Ce qu'est l'intrication quantique",
"Pourquoi les miroirs inversent la gauche et la droite",
"Comment le son se propage",
"Ce qui crée un arc-en-ciel",
"Pourquoi l'air chaud monte",
"Comment fonctionne un réacteur nucléaire",
"Ce que pourrait être la matière noire",
"Pourquoi le temps ralentit près de la lumière",
"Comment se forment les trous noirs",
"Pourquoi la Lune cause les marées",
"Ce qu'est une étoile à neutrons",
"Comment les étoiles fabriquent les éléments",
"Pourquoi Mars est rouge",
"Comment les fusées atteignent l'orbite",
"Ce qu'était le Big Bang",
"Pourquoi Pluton n'est pas une planète",
"Comment le GPS utilise la relativité",
"Ce qui cause les éclipses solaires",
"Comment les télescopes voient le passé",
"Pourquoi les galaxies sont en spirale",
"Ce que mesure une année-lumière",
"Comment le Soleil produit son énergie",
"Pourquoi l'espace est froid mais le soleil brûle",
"Ce qui cause les saisons",
"Comment les comètes ont une queue",
"Pourquoi l'univers est en expansion",
"Ce que sont les exoplanètes",
"Comment se forment les aurores",
"Comment fonctionnent les vaccins",
"Pourquoi les oignons font pleurer",
"Comment la mémoire se forme",
"Pourquoi nous rêvons",
"Comment les muscles se développent",
"Ce qui cause le vieillissement",
"Comment les antibiotiques tuent les bactéries",
"Pourquoi nous avons de la fièvre",
"Comment le système immunitaire apprend",
"Ce que fait vraiment l'ADN",
"Comment les nerfs transmettent des signaux",
"Pourquoi nous bâillons",
"Comment le cœur garde son rythme",
"Ce que font les bactéries intestinales",
"Comment les blessures guérissent",
"Pourquoi nous avons besoin de dormir",
"Comment les yeux perçoivent la couleur",
"Ce qui cause les allergies",
"Comment les cellules se divisent",
"Pourquoi l'exercice développe l'endurance",
"Pourquoi le savon nettoie",
"Comment les batteries stockent l'énergie",
"Ce qui rend une substance acide",
"Comment on fabrique le verre",
"Pourquoi les métaux conduisent l'électricité",
"Comment les feux d'artifice ont des couleurs",
"Ce qu'est vraiment la rouille",
"Comment les catalyseurs accélèrent les réactions",
"Pourquoi l'huile et l'eau ne se mélangent pas",
"Comment on fabrique le plastique",
"Ce que mesure le pH",
"Comment fonctionne la fermentation",
"Pourquoi le diamant est dur",
"Comment se forment les bulles de savon",
"Ce qui rend les piments forts",
"Comment fonctionne la glace sèche",
"Pourquoi le pain lève",
"Comment le parfum se diffuse",
"Ce que sont les alliages",
"Comment fonctionne la datation au carbone",
"Le contrôle de congestion TCP",
"Comment le chiffrement protège les secrets",
"Ce que fait un index de base de données",
"Comment les réseaux de neurones apprennent",
"Pourquoi les mots de passe sont hachés",
"Comment Internet achemine les données",
"Ce que fait un compilateur",
"Comment le GPS trouve votre position",
"Pourquoi les ordinateurs utilisent le binaire",
"Comment un processeur exécute du code",
"Ce que résout vraiment le cache",
"Comment le Wi-Fi transporte les données",
"Ce qu'est vraiment la blockchain",
"Comment les moteurs de recherche classent les pages",
"Pourquoi la RAM est plus rapide que le disque",
"Comment fonctionne la compression d'images",
"Ce qu'est une API",
"Comment fonctionne la cryptographie à clé publique",
"Pourquoi les logiciels ont des bugs",
"Comment fonctionne la traduction automatique",
"Pourquoi les nombres premiers comptent",
"Ce que mesure le calcul différentiel",
"Comment fonctionnent les probabilités",
"Pourquoi pi est partout",
"Ce que signifie vraiment l'infini",
"Ce que révèle une dérivée",
"Pourquoi le zéro fut révolutionnaire",
"Comment les statistiques peuvent tromper",
"Ce que signifie la croissance exponentielle",
"Pourquoi certains problèmes sont insolubles",
"Comment les intérêts composés croissent",
"Ce qu'est un logarithme",
"Pourquoi la courbe en cloche apparaît",
"Comment on crée les fractales",
"Ce que fait le théorème de Bayes",
"Pourquoi on ne peut pas diviser par zéro",
"Comment le GPS triangule une position",
"Ce que représente une matrice",
"Pourquoi le hasard est difficile",
"Comment les banques fixent les taux",
"Ce qui cause l'inflation",
"Comment fonctionnent les marchés boursiers",
"Pourquoi l'argent a de la valeur",
"Ce qu'est une récession",
"Comment les impôts influencent les comportements",
"Pourquoi les prix montent et baissent",
"Ce que signifie l'offre et la demande",
"Comment l'assurance répartit le risque",
"Pourquoi le commerce profite aux deux camps",
"Ce que mesure le PIB",
"Comment fonctionnent les scores de crédit",
"Pourquoi les bulles se forment et éclatent",
"Comment évoluent les taux de change",
"Pourquoi les monopoles sont risqués",
"Ce qu'est une obligation",
"Comment fonctionne le capital-risque",
"Pourquoi la diversification compte",
"Ce qu'explique la théorie des jeux",
"Comment l'imprimerie a changé l'Europe",
"Pourquoi les empires s'effondrent",
"Comment l'écriture fut inventée",
"Ce qui a causé la révolution industrielle",
"Pourquoi l'Empire romain est tombé",
"Comment la monnaie a remplacé le troc",
"Ce qui a déclenché la Renaissance",
"Comment la démocratie a commencé",
"Pourquoi la Route de la soie comptait",
"Ce qu'ont changé les Lumières",
"Comment les épidémies ont remodelé la société",
"Pourquoi les frontières sont là où elles sont",
"Comment les familles de langues se sont répandues",
"Ce qui a causé la guerre froide",
"Comment les premières villes sont nées",
"Pourquoi les révolutions arrivent",
"Comment la navigation a ouvert le monde",
"Ce qu'était vraiment la féodalité",
"Comment le calendrier fut fixé",
"Pourquoi certaines civilisations ont disparu",
"Comment se produisent les tremblements de terre",
"Pourquoi les volcans entrent en éruption",
"Ce qui cause la météo",
"Comment se forment les montagnes",
"Pourquoi l'océan est salé",
"Comment les rivières façonnent le paysage",
"Ce qui anime les courants océaniques",
"Pourquoi les déserts se forment où ils sont",
"Comment se forment les fossiles",
"Comment les nuages forment la pluie",
"Pourquoi le climat change",
"Comment grandissent les récifs coralliens",
"Ce qu'explique la tectonique des plaques",
"Comment se forment les grottes",
"Pourquoi les feuilles changent de couleur",
"Comment se forme la foudre",
"De quoi le sol est fait",
"Comment les glaciers se déplacent",
"Pourquoi certaines régions ont des moussons",
"Pourquoi nous procrastinons",
"Comment se forment les habitudes",
"Pourquoi la musique nous émeut",
"Comment nous apprenons les langues",
"Ce qui rend les choses virales",
"Pourquoi les illusions d'optique nous trompent",
"Comment marchent les astuces de mémoire",
"Pourquoi nous ressentons le déjà-vu",
"Comment fonctionne la persuasion",
"Ce qui rend une mélodie entêtante",
"Pourquoi les foules agissent irrationnellement",
"Comment se développent les accents",
"Pourquoi nous voyons des visages partout",
"Comment fonctionne l'effet placebo",
"Pourquoi les délais stimulent la concentration",
"Comment la couleur influence l'humeur",
"Pourquoi les histoires nous marquent",
"Comment le cerveau bilingue change de langue",
"Pourquoi nous oublions les noms",
"Comment fonctionne vraiment l'attention"
],
"spark": "Surprenez-moi",
"sparking": "Recherche en cours…",
"or": "ou",
"depthLabel": "Profondeur de la leçon",
"depth": {
"quick": "Express",
"quickMeta": "~5 min",
"standard": "Standard",
"standardMeta": "~10 min",
"deep": "Approfondi",
"deepMeta": "~20 min"
},
"modeLabel": "Format",
"mode": {
"practice": "Exercices",
"read": "Lecture seule"
},
"continue": {
"heading": "Reprendre",
"lessonProgress": "Leçon {position} sur {total}",
"resume": "Reprendre →"
},
"dueReviews": "{count} à réviser →"
},
"auth": {
"login": {
"title": "Connexion",
"email": "Email",
"password": "Mot de passe",
"submit": "Se connecter",
"submitting": "Connexion…",
"error": "Email ou mot de passe incorrect.",
"forgotPassword": "Mot de passe oublié ?",
"noAccount": "Pas de compte ?",
"register": "S'inscrire",
"resetSuccess": "Mot de passe mis à jour. Connectez-vous avec votre nouveau mot de passe.",
"or": "ou",
"continueWithGoogle": "Continuer avec Google",
"continueWithGitHub": "Continuer avec GitHub",
"continueWith": "Continuer avec {provider}"
},
"register": {
"title": "Créer un compte",
"name": "Nom",
"email": "Email",
"password": "Mot de passe",
"confirmPassword": "Confirmer le mot de passe",
"passwordMismatch": "Les mots de passe ne correspondent pas.",
"submit": "Créer un compte",
"submitting": "Création en cours…",
"signInFailed": "Compte créé mais la connexion a échoué. Essayez de vous connecter manuellement.",
"hasAccount": "Déjà un compte ?",
"signIn": "Se connecter"
},
"forgotPassword": {
"title": "Réinitialiser le mot de passe",
"email": "Email",
"submit": "Envoyer le lien",
"submitting": "Envoi…",
"sentTitle": "Vérifiez votre boîte mail",
"sentBody": "Si un compte existe pour cet email, nous avons envoyé un lien de réinitialisation. Il expire dans 1 heure.",
"backToSignIn": "Retour à la connexion",
"error": "Une erreur s'est produite. Réessayez."
},
"resetPassword": {
"title": "Définir un nouveau mot de passe",
"newPassword": "Nouveau mot de passe",
"confirmPassword": "Confirmer le mot de passe",
"passwordMismatch": "Les mots de passe ne correspondent pas.",
"submit": "Enregistrer",
"submitting": "Enregistrement…",
"error": "Échec de la réinitialisation du mot de passe.",
"invalidLink": "Lien de réinitialisation invalide.",
"requestNew": "Demander un nouveau lien"
},
"acceptInvite": {
"title": "Accepter votre invitation",
"subtitle": "Configurez votre compte pour commencer.",
"email": "E-mail",
"name": "Votre nom",
"password": "Mot de passe",
"confirmPassword": "Confirmer le mot de passe",
"passwordMismatch": "Les mots de passe ne correspondent pas.",
"submit": "Créer le compte",
"submitting": "Création…",
"error": "Impossible daccepter cette invitation.",
"invalidLink": "Ce lien dinvitation est invalide, expiré ou déjà utilisé.",
"goToLogin": "Aller à la connexion"
},
"verifyEmail": {
"title": "Vérifiez votre email",
"body": "Nous avons envoyé un lien de vérification à votre adresse email. Cliquez dessus pour activer votre compte.",
"subtext": "Vous ne l'avez pas reçu ? Vérifiez vos spams."
},
"error": {
"title": "Erreur d'authentification",
"default": "Une erreur s'est produite lors de la connexion.",
"Configuration": "Erreur de configuration du serveur. Contactez le support.",
"AccessDenied": "Accès refusé.",
"Verification": "Le lien de vérification a expiré ou a déjà été utilisé.",
"backToSignIn": "Retour à la connexion"
}
},
"settings": {
"title": "Paramètres",
"profile": {
"title": "Profil",
"name": "Nom affiché",
"save": "Enregistrer",
"saving": "Enregistrement…",
"saved": "Enregistré.",
"saveFailed": "Échec de l'enregistrement."
},
"language": {
"title": "Langue",
"label": "Langue de l'interface",
"description": "Choisissez la langue utilisée dans toute l'application.",
"en": "English",
"fr": "Français"
},
"security": {
"title": "Sécurité",
"currentPassword": "Mot de passe actuel",
"newPassword": "Nouveau mot de passe",
"confirmPassword": "Confirmer le nouveau mot de passe",
"changePassword": "Changer le mot de passe",
"changing": "Modification…",
"changed": "Mot de passe modifié.",
"failed": "Échec.",
"oauthNote": "Le changement de mot de passe n'est pas disponible pour les comptes utilisant la connexion sociale.",
"linked": "Connexion via : {providers}",
"passwordMismatch": "Les nouveaux mots de passe ne correspondent pas."
},
"appearance": {
"title": "Apparence",
"theme": {
"label": "Thème",
"system": "Système",
"light": "Clair",
"dark": "Sombre"
}
},
"danger": {
"title": "Zone dangereuse",
"deleteAccount": "Supprimer le compte",
"deleteConfirm": "Supprimer mon compte",
"deleteWarning": "Cette action supprimera définitivement votre compte et toutes vos données d'apprentissage. Elle est irréversible.",
"deleting": "Suppression…"
},
"learning": {
"title": "Apprentissage",
"description": "Personnalisez la façon dont les leçons sont rédigées pour vous.",
"ageGroup": {
"label": "Pour qui est-ce ?",
"child": "Enfant (812 ans)",
"teen": "Adolescent (1317 ans)",
"adult": "Adulte"
},
"difficulty": {
"label": "Niveau de difficulté par défaut",
"1": "Débutant",
"2": "Intermédiaire",
"3": "Avancé"
},
"depth": {
"label": "Durée de leçon par défaut",
"quick": "Courte (~5 min)",
"standard": "Standard (~10 min)",
"deep": "Approfondie (~20 min)"
},
"hint": {
"label": "À propos de vous (optionnel)",
"placeholder": "p. ex. Je suis infirmière, j'aime les analogies avec la cuisine…",
"description": "Une courte note aide à adapter les explications à votre profil."
},
"save": "Enregistrer",
"saving": "Enregistrement…",
"saved": "Enregistré.",
"saveFailed": "Échec de l'enregistrement."
},
"notifications": {
"title": "Notifications",
"description": "Gérez comment Curio vous contacte.",
"emailDigest": "M'envoyer un email quotidien quand des révisions sont en attente"
}
},
"onboarding": {
"title": "Bienvenue sur Curio",
"subtitle": "Configurez votre profil d'apprentissage. Vous pourrez le modifier à tout moment.",
"ageGroup": {
"label": "Pour qui est-ce ?",
"child": "Enfant (812 ans)",
"teen": "Adolescent (1317 ans)",
"adult": "Adulte"
},
"difficulty": {
"label": "Quel est votre niveau habituel ?",
"1": "Débutant — partir de zéro",
"2": "Intermédiaire — partir des bases",
"3": "Avancé — aller en profondeur"
},
"depth": {
"label": "Durée de leçon préférée",
"quick": "Courte (~5 min)",
"standard": "Standard (~10 min)",
"deep": "Approfondie (~20 min)"
},
"hint": {
"label": "Parlez-nous de vous (optionnel)",
"placeholder": "p. ex. Je suis infirmière, j'aime les analogies avec la cuisine…",
"description": "Aide à adapter les explications à votre profil."
},
"submit": "Commencer",
"submitting": "Enregistrement…",
"skip": "Passer pour l'instant"
},
"masteryMap": {
"title": "Carte de maîtrise",
"loading": "Chargement…",
"empty": "Aucune donnée de maîtrise pour l'instant.",
"emptyLink": "Commencer à apprendre",
"due": "à revoir",
"dueZone": {
"heading": "À réviser",
"startReview": "Commencer la révision →",
"none": "Rien à revoir pour l'instant."
},
"overview": {
"mastered": "Maîtrisés",
"learning": "En cours",
"needsWork": "À revoir",
"progress": "{mastered} concept{mastered, plural, one {} other {s}} maîtrisé{mastered, plural, one {} other {s}} sur {total}"
},
"status": {
"mastered": "Maîtrisé",
"learning": "En cours",
"needsWork": "À revoir",
"notStarted": "Non commencé"
},
"filter": {
"all": "Tout",
"due": "À réviser",
"needsWork": "À consolider"
},
"remove": "Retirer",
"removeBlueprint": "Retirer {title} de la carte de maîtrise"
},
"profile": {
"title": "Votre profil",
"masteryTitle": "Aperçu de la maîtrise",
"noMastery": "Aucune donnée de maîtrise pour l'instant. Commencez à apprendre pour voir votre progression ici."
},
"grade": {
"verdict": {
"mastered": "Compris",
"partial": "Partiel",
"misconception": "Erreur de compréhension",
"uncertain": "Incertain"
},
"calibration": {
"confidentFailed": "Vous vous êtes senti confiant — cela vaut la peine de réfléchir à ce qui vous a fait trébucher.",
"unsurePassed": "Vous vous êtes dit incertain, mais votre réponse était solide. Faites confiance à votre compréhension."
},
"referenceHeading": "Réponse complète",
"ariaFeedback": "Retour du tuteur",
"ariaCalibration": "Note de calibration",
"socratic": {
"ariaLabel": "Question socratique",
"placeholder": "Allez-y…",
"ariaInput": "Réponse de suivi",
"submit": "Répondre",
"considering": "En cours d'évaluation…"
},
"reexplain": {
"loading": "Préparation d'une autre explication…",
"trigger": "Essayer une autre explication →"
},
"retry": "Réessayer →",
"report": {
"toggle": "Signaler un problème",
"ariaLabel": "Signaler un problème",
"thanks": "Merci — nous allons examiner ça.",
"reasonGradeWrong": "La note semble incorrecte",
"reasonContentError": "Erreur de contenu",
"reasonOther": "Autre",
"notesPlaceholder": "Détails optionnels…",
"ariaReason": "Raison",
"ariaDetails": "Détails",
"submit": "Envoyer",
"cancel": "Annuler"
}
}
}