feat: page interactive, démos Play/Step et simulateur Carnot

Ajoute le pipeline PageSpec (validation, rendu, publication /p/{slug}),
les démos TipTap /demo, et le simulateur Carnot (modes frigo/PAC/moteur,
énergie kJ vs puissance W, unités K/°C/°F) avec correctifs d’équations KaTeX.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Antigravity
2026-07-24 17:51:43 +00:00
parent f385d43d5d
commit 69c99e4f4f
67 changed files with 12005 additions and 33 deletions

View File

@@ -38,7 +38,24 @@
"createYourSpaceSubtitle": "Join the new era of smart note-taking.",
"forgot": "Forgot?",
"backToSite": "Back to site",
"privacyTerms": "© 2025 Memento Labs — Privacy · Terms"
"privacyTerms": "© 2025 Memento Labs — Privacy · Terms",
"checkEmailTitle": "Check your email",
"checkEmailDescription": "We sent a confirmation link to {email}. Open it to activate your account before signing in.",
"checkEmailDescriptionGeneric": "We sent a confirmation link to your email. Open it to activate your account before signing in.",
"resendVerification": "Resend confirmation email",
"verifyResent": "Confirmation email sent. Check your inbox.",
"verifyResendFailed": "Could not send the confirmation email. Try again later.",
"verifyMissingEmail": "Enter your email address.",
"verifyLoading": "Confirming your email…",
"verifySuccessTitle": "Email confirmed",
"verifySuccessDescription": "Your account is ready. You can now sign in.",
"verifyExpiredTitle": "Link expired",
"verifyExpiredDescription": "This confirmation link has expired. Request a new one.",
"verifyInvalidTitle": "Invalid link",
"verifyInvalidDescription": "This confirmation link is invalid or already used.",
"emailNotVerified": "Please confirm your email before signing in.",
"emailVerifiedBanner": "Email confirmed. You can sign in now.",
"invalidCredentials": "Invalid email or password."
},
"sidebar": {
"notes": "Notes",
@@ -792,6 +809,18 @@
"formal": "Formal",
"casual": "Casual"
},
"interactiveDemo": {
"invalid": "Invalid interactive demo",
"empty": "Interactive demo unavailable",
"step": "step",
"speed": "Playback speed",
"needMoreText": "Select at least ~20 words (or write more content) to generate a demo",
"generating": "Generating interactive demo…",
"generateSuccess": "Interactive demo inserted",
"generateFailed": "Demo generation failed",
"insertFailed": "Could not insert the demo",
"quotaExceeded": "Not enough AI quota"
},
"memoryEcho": {
"title": "I noticed something...",
"description": "Proactive connections between your notes",
@@ -1602,7 +1631,58 @@
"notSynced": "Not synced yet (cron /api/cron/sync-usage)",
"byFeature": "By feature (PostgreSQL)",
"topUsers": "Top users",
"noUsageData": "No usage data for this period yet"
"noUsageData": "No usage data for this period yet",
"healthTitle": "Stripe health check",
"healthDescription": "Runtime status of keys, webhooks, price IDs and billing flag (secrets are never shown).",
"healthSecret": "Secret key (server)",
"healthPublishable": "Publishable key",
"healthWebhook": "Webhook secret",
"healthBillingFlag": "Billing enabled",
"healthTrial": "Free trial",
"trialDaysValue": "{days} days on first checkout",
"modeTest": "Test mode (sk_test_…)",
"modeLive": "Live mode (sk_live_…)",
"modePlaceholder": "Placeholder / invalid key",
"modeMissing": "Not configured",
"configured": "Configured",
"missing": "Missing",
"enabled": "Enabled",
"disabled": "Disabled",
"priceStatusTitle": "Price IDs vs Stripe",
"colKey": "Plan",
"colPriceId": "Price ID",
"colSource": "Source",
"colStripe": "Stripe amount",
"priceError": "Lookup failed",
"inactive": "inactive",
"notChecked": "Not checked (no Stripe key)",
"subsTitle": "Subscriptions overview",
"subsDescription": "Counts from the local database (synced via Stripe webhooks).",
"statPaid": "Active + trial",
"statTrialing": "On trial",
"statPastDue": "Past due",
"statCanceling": "Cancel at period end",
"byTier": "By tier",
"byStatus": "By status",
"usersWithoutSub": "Users with no Subscription row",
"noSubs": "No subscriptions yet",
"recentSubs": "Recent paid / trial accounts",
"colUser": "User",
"colTier": "Tier",
"colStatus": "Status",
"colPeriod": "Period / trial end",
"canceling": "canceling",
"manualTier": "manual (no Stripe sub)",
"trialUntil": "Trial until {date}",
"testGuideTitle": "How to test Stripe locally",
"testGuideDescription": "Checklist to validate checkout, webhooks and trial.",
"testStep1": "Stripe Dashboard → Test mode ON. Create Pro/Business products + monthly/annual prices + credit packs.",
"testStep2": "Put sk_test_…, pk_test_… in .env. Put price_… IDs in Admin → Billing (or env) and enable billing.",
"testStep3": "Copy the whsec_… into STRIPE_WEBHOOK_SECRET and restart the app.",
"testStep4": "npm run dev → open /settings/billing as a BASIC user.",
"testStep5": "Start Pro checkout. Card: 4242 4242 4242 4242, any future expiry, any CVC. Expect a 7-day trial.",
"testStep6": "Confirm Admin → Billing shows TRIALING, and /settings/billing shows the trial end date.",
"testCardHint": "Other cards: 4000000000009995 = payment fails · 4000002500003155 = 3D Secure. Never use real cards in test mode."
},
"dashboard": {
"title": "Dashboard",
@@ -1812,6 +1892,8 @@
"featureBrainstormCreate": "Brainstorm creations",
"featureBrainstormSessions": "Brainstorm sessions",
"featureCharts": "AI Charts",
"featureInteractiveDemo": "Interactive demos",
"featureInteractivePage": "Interactive pages",
"featurePublishEnhance": "AI Publishing",
"featureBrainstormExpand": "Brainstorm expansions",
"featureBrainstormEnrich": "Brainstorm enrichments",
@@ -2579,6 +2661,8 @@
"slashTableDesc": "Insert a simple grid",
"slashDatabase": "Structured View",
"slashDatabaseDesc": "Embed your notebook's structured data",
"slashInteractiveDemo": "Interactive Demo",
"slashInteractiveDemoDesc": "AI step-by-step teaching demo (Play / Step)",
"slashToggle": "Toggle Section",
"slashToggleDesc": "Create a collapsible section",
"slashCallout": "Callout",
@@ -2726,6 +2810,21 @@
"publishTemplateMagazine": "Magazine article",
"publishTemplateBrief": "Expert brief",
"publishTemplateEssay": "Essay",
"publishTemplateInteractivePage": "Interactive page",
"publishInteractivePage": "Interactive page",
"publishInteractivePageHint": "AI-generated page: hero, sections, Play/Step demos — 20 credits",
"publishInteractivePageGenerating": "Building interactive page…",
"publishInteractivePageGeneratingWait": "Almost ready…",
"publishInteractivePageGeneratingLong": "Still working…",
"publishInteractivePagePlanning": "Analyzing content — planning the page…",
"publishInteractivePageSectionProgress": "Section {current}/{total}: {title}",
"publishInteractivePageFallback": "AI generation unavailable — showing simplified page",
"publishInteractivePagePartialFallback": "Some sections were generated in simplified mode",
"publishInteractivePageTooShort": "Note too short — add more content and try again",
"publishInteractivePageSuccess": "Interactive page published!",
"publishInteractivePageFailed": "Interactive page generation failed",
"publishInteractivePagePreviewHint": "Preview — review, then publish to the public URL",
"publishInteractivePageConfirm": "Publish page",
"publishAiSuccess": "AI-enhanced page published!",
"publishRewriteLabel": "Rewrite for the web",
"publishRewriteOnHint": "Structures your editor blocks (exercises, toggles, callouts) for the web — AI writes only the intro",
@@ -3381,7 +3480,11 @@
"fetchStatusFailed": "Failed to fetch billing status",
"fetchQuotasFailed": "Failed to load credit usage",
"fetchInvoicesFailed": "Failed to load billing history.",
"savePercent": "Save ~17%"
"savePercent": "Save ~17%",
"startTrialCta": "Start {days}-day free trial",
"trialFeature": "{days}-day free trial (card required)",
"trialEndsOn": "Your free trial ends on {date}. You will then be billed automatically.",
"trialEndsLabel": "Trial ends"
},
"quotaPaywall": {
"title": "Out of AI credits",
@@ -3528,6 +3631,12 @@
"perMonthAnnual": "/mo, billed yearly",
"perUser": "+ €3.90/user",
"perUserAnnual": "+ €2.90/user, yearly",
"savePercent": "Save ~17%",
"proMonthly": "€9.90",
"proAnnualMonthly": "€8.25",
"businessMonthly": "€29.90",
"businessAnnualMonthly": "€24.92",
"enterprisePrice": "Custom",
"popular": "Most chosen",
"basic": {
"name": "Basic",
@@ -3572,7 +3681,10 @@
"feature4": "Dedicated support",
"feature5": "Live onboarding"
},
"basicPrice": "Free"
"basicPrice": "Free",
"trialBadge": "{days}-day free trial",
"trialFeature": "{days}-day free trial (card required)",
"trialCta": "Start {days}-day free trial"
},
"cta": {
"title": "Stop losing your best ideas.",

View File

@@ -38,7 +38,24 @@
"createYourSpaceSubtitle": "Rejoignez la nouvelle ère de la prise de notes intelligente.",
"forgot": "Oublié ?",
"backToSite": "Retour",
"privacyTerms": "© 2025 Memento Labs — Confidentialité · Conditions"
"privacyTerms": "© 2025 Memento Labs — Confidentialité · Conditions",
"checkEmailTitle": "Vérifiez votre e-mail",
"checkEmailDescription": "Nous avons envoyé un lien de confirmation à {email}. Ouvrez-le pour activer votre compte avant de vous connecter.",
"checkEmailDescriptionGeneric": "Nous avons envoyé un lien de confirmation à votre e-mail. Ouvrez-le pour activer votre compte avant de vous connecter.",
"resendVerification": "Renvoyer le-mail de confirmation",
"verifyResent": "E-mail de confirmation envoyé. Vérifiez votre boîte de réception.",
"verifyResendFailed": "Impossible denvoyer le-mail de confirmation. Réessayez plus tard.",
"verifyMissingEmail": "Saisissez votre adresse e-mail.",
"verifyLoading": "Confirmation de votre e-mail…",
"verifySuccessTitle": "E-mail confirmé",
"verifySuccessDescription": "Votre compte est prêt. Vous pouvez vous connecter.",
"verifyExpiredTitle": "Lien expiré",
"verifyExpiredDescription": "Ce lien de confirmation a expiré. Demandez-en un nouveau.",
"verifyInvalidTitle": "Lien invalide",
"verifyInvalidDescription": "Ce lien de confirmation est invalide ou déjà utilisé.",
"emailNotVerified": "Confirmez votre e-mail avant de vous connecter.",
"emailVerifiedBanner": "E-mail confirmé. Vous pouvez vous connecter.",
"invalidCredentials": "E-mail ou mot de passe incorrect."
},
"sidebar": {
"notes": "Notes",
@@ -798,6 +815,18 @@
"formal": "Formel",
"casual": "Décontracté"
},
"interactiveDemo": {
"invalid": "Démo interactive invalide",
"empty": "Démo interactive indisponible",
"step": "étape",
"speed": "Vitesse de lecture",
"needMoreText": "Sélectionne au moins ~20 mots (ou écris plus de contenu) pour générer une démo",
"generating": "Génération de la démo interactive…",
"generateSuccess": "Démo interactive insérée",
"generateFailed": "Échec de la génération",
"insertFailed": "Impossible dinsérer la démo",
"quotaExceeded": "Quota IA insuffisant"
},
"memoryEcho": {
"title": "💡 J'ai remarqué quelque chose...",
"description": "Connexions proactives entre vos notes",
@@ -1608,7 +1637,58 @@
"notSynced": "Pas encore synchronisé (cron /api/cron/sync-usage)",
"byFeature": "Par fonctionnalité (PostgreSQL)",
"topUsers": "Utilisateurs les plus actifs",
"noUsageData": "Aucune donnée pour cette période"
"noUsageData": "Aucune donnée pour cette période",
"healthTitle": "État Stripe",
"healthDescription": "Statut des clés, webhooks, price IDs et flag facturation (les secrets ne sont jamais affichés).",
"healthSecret": "Clé secrète (serveur)",
"healthPublishable": "Clé publique",
"healthWebhook": "Secret webhook",
"healthBillingFlag": "Facturation activée",
"healthTrial": "Essai gratuit",
"trialDaysValue": "{days} jours au premier checkout",
"modeTest": "Mode test (sk_test_…)",
"modeLive": "Mode live (sk_live_…)",
"modePlaceholder": "Clé placeholder / invalide",
"modeMissing": "Non configurée",
"configured": "Configuré",
"missing": "Manquant",
"enabled": "Activé",
"disabled": "Désactivé",
"priceStatusTitle": "Price IDs vs Stripe",
"colKey": "Offre",
"colPriceId": "Price ID",
"colSource": "Source",
"colStripe": "Montant Stripe",
"priceError": "Échec lecture",
"inactive": "inactif",
"notChecked": "Non vérifié (pas de clé Stripe)",
"subsTitle": "Vue des abonnements",
"subsDescription": "Compteurs depuis la base locale (synchronisée via webhooks Stripe).",
"statPaid": "Actifs + essai",
"statTrialing": "En essai",
"statPastDue": "Impayés",
"statCanceling": "Résiliation fin de période",
"byTier": "Par tier",
"byStatus": "Par statut",
"usersWithoutSub": "Utilisateurs sans ligne Subscription",
"noSubs": "Aucun abonnement pour linstant",
"recentSubs": "Comptes payants / essai récents",
"colUser": "Utilisateur",
"colTier": "Tier",
"colStatus": "Statut",
"colPeriod": "Période / fin dessai",
"canceling": "résiliation",
"manualTier": "manuel (pas de sub Stripe)",
"trialUntil": "Essai jusquau {date}",
"testGuideTitle": "Comment tester Stripe en local",
"testGuideDescription": "Checklist pour valider checkout, webhooks et essai.",
"testStep1": "Stripe Dashboard → mode Test ON. Créer produits Pro/Business + prix mensuel/annuel + packs crédits.",
"testStep2": "Mettre sk_test_…, pk_test_… dans .env. Mettre les price_… dans Admin → Facturation (ou env) et activer la facturation.",
"testStep3": "Copier le whsec_… dans STRIPE_WEBHOOK_SECRET et redémarrer lapp.",
"testStep4": "npm run dev → ouvrir /settings/billing avec un compte BASIC.",
"testStep5": "Lancer le checkout Pro. Carte : 4242 4242 4242 4242, date future, CVC quelconque. Essai 7 jours attendu.",
"testStep6": "Vérifier Admin → Facturation (TRIALING) et /settings/billing (date de fin dessai).",
"testCardHint": "Autres cartes : 4000000000009995 = échec paiement · 4000002500003155 = 3D Secure. Jamais de vraie carte en mode test."
},
"dashboard": {
"title": "Tableau de bord",
@@ -1818,6 +1898,8 @@
"featureBrainstormCreate": "Créations brainstorm",
"featureBrainstormSessions": "Sessions brainstorm",
"featureCharts": "Graphiques IA",
"featureInteractiveDemo": "Démos interactives",
"featureInteractivePage": "Pages interactives",
"featurePublishEnhance": "Publication IA",
"featureBrainstormExpand": "Extensions brainstorm",
"featureBrainstormEnrich": "Enrichissements brainstorm",
@@ -2585,6 +2667,8 @@
"slashTableDesc": "Insérer un tableau simple",
"slashDatabase": "Vue structurée",
"slashDatabaseDesc": "Intégrer les données structurées de votre carnet",
"slashInteractiveDemo": "Démo interactive",
"slashInteractiveDemoDesc": "Démo pédagogique IA étape par étape (Play / Step)",
"slashToggle": "Section repliable",
"slashToggleDesc": "Créer une section dépliable",
"slashCallout": "Encadré",
@@ -2732,6 +2816,21 @@
"publishTemplateMagazine": "Article magazine",
"publishTemplateBrief": "Fiche expert",
"publishTemplateEssay": "Essai",
"publishTemplateInteractivePage": "Page interactive",
"publishInteractivePage": "Page interactive",
"publishInteractivePageHint": "Page générée par IA : hero, sections, démos Play/Step — 20 crédits",
"publishInteractivePageGenerating": "Construction de la page…",
"publishInteractivePageGeneratingWait": "Presque prêt…",
"publishInteractivePageGeneratingLong": "Toujours en cours…",
"publishInteractivePagePlanning": "Analyse du contenu — plan de la page…",
"publishInteractivePageSectionProgress": "Section {current}/{total} : {title}",
"publishInteractivePageFallback": "Génération IA indisponible — page simplifiée affichée",
"publishInteractivePagePartialFallback": "Certaines sections ont été générées en mode simplifié",
"publishInteractivePageTooShort": "Note trop courte — ajoutez du contenu puis réessayez",
"publishInteractivePageSuccess": "Page interactive publiée !",
"publishInteractivePageFailed": "Échec de la page interactive",
"publishInteractivePagePreviewHint": "Aperçu — vérifiez puis publiez sur lURL publique",
"publishInteractivePageConfirm": "Publier la page",
"publishAiSuccess": "Page publiée avec mise en page IA !",
"publishRewriteLabel": "Reformuler pour le web",
"publishRewriteOnHint": "Structure vos blocs éditeur (exercices, toggles, encadrés) en page web — l'IA rédige seulement le chapô",
@@ -3387,7 +3486,11 @@
"fetchStatusFailed": "Échec du chargement des informations de facturation",
"fetchQuotasFailed": "Échec du chargement des crédits",
"fetchInvoicesFailed": "Impossible de charger l'historique de facturation.",
"savePercent": "Économisez ~17%"
"savePercent": "Économisez ~17%",
"startTrialCta": "Essai gratuit {days} jours",
"trialFeature": "Essai gratuit {days} jours (carte requise)",
"trialEndsOn": "Votre essai gratuit se termine le {date}. Vous serez ensuite facturé automatiquement.",
"trialEndsLabel": "Fin de l'essai"
},
"quotaPaywall": {
"title": "Plus de crédits IA",
@@ -3534,6 +3637,12 @@
"perMonthAnnual": "/mois, facturé à l'année",
"perUser": "+ 3,90€/user",
"perUserAnnual": "+ 2,90€/user, à l'année",
"savePercent": "~17 %",
"proMonthly": "9,90€",
"proAnnualMonthly": "8,25€",
"businessMonthly": "29,90€",
"businessAnnualMonthly": "24,92€",
"enterprisePrice": "Sur devis",
"popular": "Le plus choisi",
"basic": {
"name": "Basic",
@@ -3578,7 +3687,10 @@
"feature4": "Support dédié",
"feature5": "Onboarding live"
},
"basicPrice": "Gratuit"
"basicPrice": "Gratuit",
"trialBadge": "Essai gratuit {days} jours",
"trialFeature": "Essai gratuit {days} jours (carte requise)",
"trialCta": "Essayer {days} jours gratuitement"
},
"cta": {
"title": "Arrêtez de perdre vos meilleures idées.",