feat(plugin): i18n FR + EN (Phase 4.2)

Infrastructure i18n légère, sans deps externe :

- lib/i18n/types.ts : LOCALES, DEFAULT_LOCALE, cookie name
- lib/i18n/server.ts : getLocale (cookie > Accept-Language > FR),
  t(key) async server-side, dict(locale)
- lib/i18n/client.tsx : LocaleProvider + useLocale + useT
- messages/fr.json + messages/en.json : ~50 clés pour landing + header + footer
- LocaleSwitcher component (cookie + router.refresh)

Plugin gated :
- Quand i18n-fr-en désactivé, getLocale() force FR. Le switcher ne s'affiche
  pas dans le hero. Pas d'impact sur le rendu existant.
- Quand activé, switcher visible coin haut-droit du hero. Les composants
  landing/header/footer rendent en FR ou EN selon le cookie utilisateur.

Composants i18n-isés :
- HeroSection (eyebrow, titre, CTA)
- ExperiencesSection (route/fleuve vs expédition, tous les bullets)
- HowItWorksSection (3 étapes)
- CESection (KPIs + body + CTA)
- TestimonialsSection (eyebrow + titre, citations restent en VO)
- Footer (taglines, colonnes)
- SeasonBanner (3 saisons + messages)
- AccessTypeBadge (labels + tooltips)

Pour les ContentPage, le champ lang existait déjà. Une suite (PR ultérieure)
ajoutera le filtre lang dans getContentPage + seed pages EN.
This commit is contained in:
Claude Integration 2026-05-31 11:38:39 +00:00
parent efeea16467
commit cf9da94bb5
15 changed files with 454 additions and 116 deletions

71
src/messages/en.json Normal file
View file

@ -0,0 +1,71 @@
{
"site.tagline": "Karbé — riverside carbets of French Guiana",
"site.description": "The not-for-profit marketplace to rent a carbet along the rivers of French Guiana.",
"hero.eyebrow": "Solidarity marketplace — zero commission on stays",
"hero.titleLine1": "The sleeping karbé",
"hero.titleAccent": "is waiting for you",
"hero.subtitle": "Rent a carbet along the Maroni, Approuague or Oyapock. The hammock is up, the pirogue glides, the silence is real. For a few nights, the river is yours.",
"hero.ctaDiscover": "Find a carbet",
"hero.ctaPropose": "List mine",
"experiences.eyebrow": "Two ways to live Karbé",
"experiences.title": "From riverbank to pirogue expedition.",
"experiences.subtitle": "Pick the carbet you reach by car for an easy weekend — or the one you can only reach by pirogue, hours from the last village.",
"experiences.roadFluve.tag": "🛣️ Road + river",
"experiences.roadFluve.title": "The weekend carbet",
"experiences.roadFluve.body": "Accessible by track from Kourou, Saint-Laurent or Régina. Park the car, grab your gear, you're there. For families, couples who want quiet without logistics, social committees booking short stays.",
"experiences.roadFluve.b1": "1 to 3 nights typical",
"experiences.roadFluve.b2": "Car or 4WD depending on the track",
"experiences.roadFluve.b3": "Equipped carbets, swimming possible",
"experiences.riverOnly.tag": "🛶 River expedition",
"experiences.riverOnly.title": "The carbet you earn",
"experiences.riverOnly.body": "No road. Board a pirogue at a 'dégrad', sometimes two or three hours upriver. For those who really want to sleep far — howler monkeys, sky without halo, the river five meters from your hammock.",
"experiences.riverOnly.b1": "2 nights minimum recommended",
"experiences.riverOnly.b2": "Pirogue with skipper (host or partner)",
"experiences.riverOnly.b3": "Dry season recommended (July-November)",
"howItWorks.eyebrow": "How it works",
"howItWorks.title": "Three steps to disappear.",
"howItWorks.step1.title": "Choose the river",
"howItWorks.step1.body": "Maroni, Approuague, Comté, Oyapock — each river has its mood, its embarkation point, its carbets. Filter by your level of adventure.",
"howItWorks.step2.title": "Book the carbet",
"howItWorks.step2.body": "Dates, party size, pirogue duration if needed. Secure Stripe payment, paid in full to the host — zero commission on the stay.",
"howItWorks.step3.title": "Sleep for real",
"howItWorks.step3.body": "The host (or their partner) picks you up at the dégrad if needed. You get the keys to the karbé, hang the hammock, listen. Nothing left to do.",
"ce.eyebrow": "For social committees",
"ce.title": "Carbets sleep when you're not there.",
"ce.titleAccent": "Let's share them.",
"ce.body": "Karbé is built so that social committees who already own a carbet can reserve it for their members on selected weekends, then open it to public travellers the rest of the year. Zero commission on stays: the payment goes straight back to the committee.",
"ce.kpi.commission": "commission on stays",
"ce.kpi.ceFirst": "your members book first",
"ce.kpi.publicOpen": "remaining dates feed the pot",
"ce.kpi.noPaperwork": "Stripe charges and remits directly",
"ce.cta": "Learn more for your committee",
"testimonials.eyebrow": "No marketing",
"testimonials.title": "They told us, just like that.",
"footer.tagline": "Marketplace for riverside carbets of French Guiana. Solidarity with local social committees. Zero commission on stays.",
"footer.col.discover": "Discover",
"footer.col.propose": "Host",
"footer.col.legal": "Legal",
"footer.copyright": "non-profit digital project in French Guiana.",
"season.dry": "Dry season",
"season.lowWater": "Low water",
"season.wet": "Rainy season",
"season.dry.message": "Optimal conditions: rivers navigable, roads in good shape, sunrise over burning water.",
"season.lowWater.message": "Low water period: river-only carbets may not be reachable. Filter available on the search page.",
"season.wet.message": "Frequent rain: the jungle is dense and alive, plan an adapted vehicle for road+river carbets.",
"access.roadAndRiver": "🛣️ Road + river",
"access.riverOnly": "🛶 River expedition",
"access.roadAndRiver.title": "Accessible by road and by river.",
"access.riverOnly.title": "Reachable only by pirogue from a 'dégrad'.",
"language.switch": "Language",
"language.fr": "Français",
"language.en": "English"
}

71
src/messages/fr.json Normal file
View file

@ -0,0 +1,71 @@
{
"site.tagline": "Karbé — carbets fluviaux de Guyane",
"site.description": "La marketplace solidaire pour louer un carbet le long des fleuves de Guyane.",
"hero.eyebrow": "Marketplace solidaire — sans commission sur le séjour",
"hero.titleLine1": "Le karbé qui dort",
"hero.titleAccent": "vous attend",
"hero.subtitle": "Louez un carbet le long du Maroni, de l'Approuague ou de l'Oyapock. Le hamac est tendu, la pirogue glisse, le silence est vrai. Pour quelques nuits, le fleuve vous appartient.",
"hero.ctaDiscover": "Découvrir un carbet",
"hero.ctaPropose": "Proposer le mien",
"experiences.eyebrow": "Deux façons de vivre Karbé",
"experiences.title": "Du bord du fleuve à l'expédition pirogue.",
"experiences.subtitle": "Selon l'envie, on choisit le carbet qui se rejoint en voiture pour un week-end facile, ou celui qu'on n'atteint qu'en pirogue, à plusieurs heures du dernier village.",
"experiences.roadFluve.tag": "🛣️ Route + fleuve",
"experiences.roadFluve.title": "Le carbet du week-end",
"experiences.roadFluve.body": "Accessible par la piste depuis Kourou, Saint-Laurent ou Régina. Garez la voiture, prenez vos affaires et vous y êtes. Pour les familles, les couples qui veulent du calme sans logistique, les CE qui réservent des séjours courts.",
"experiences.roadFluve.b1": "1 à 3 nuits typiques",
"experiences.roadFluve.b2": "Voiture ou 4×4 selon la piste",
"experiences.roadFluve.b3": "Carbets équipés, baignade possible",
"experiences.riverOnly.tag": "🛶 Expédition fleuve",
"experiences.riverOnly.title": "Le carbet qu'on mérite",
"experiences.riverOnly.body": "Aucune route n'y mène. On embarque en pirogue depuis un dégrad, parfois deux ou trois heures de remontée. Pour ceux qui veulent vraiment dormir loin — singes hurleurs, ciel sans halo, l'eau du fleuve à 5 mètres du hamac.",
"experiences.riverOnly.b1": "2 nuits minimum recommandées",
"experiences.riverOnly.b2": "Pirogue avec passeur (loueur ou partenaire)",
"experiences.riverOnly.b3": "Saison sèche conseillée (juillet-novembre)",
"howItWorks.eyebrow": "Comment ça marche",
"howItWorks.title": "Trois étapes pour s'échapper.",
"howItWorks.step1.title": "Choisissez le fleuve",
"howItWorks.step1.body": "Maroni, Approuague, Comté, Oyapock — chaque fleuve a son ambiance, son embarquement, ses carbets. Filtrez selon votre niveau d'aventure.",
"howItWorks.step2.title": "Réservez le carbet",
"howItWorks.step2.body": "Dates, capacité, durée de pirogue le cas échéant. Paiement sécurisé Stripe, reversé au loueur sans commission sur le séjour.",
"howItWorks.step3.title": "Dormez vrai",
"howItWorks.step3.body": "Le loueur (ou son partenaire) vous récupère au dégrad si besoin. Vous récupérez les clés du karbé, tendez le hamac, écoutez. Plus rien à faire.",
"ce.eyebrow": "Pour comités d'entreprise",
"ce.title": "Les carbets dorment quand vous n'y êtes pas.",
"ce.titleAccent": "Partageons-les.",
"ce.body": "Karbé est conçu pour que les comités sociaux possédant déjà un carbet le réservent à leurs membres certains week-ends, et l'ouvrent au public touriste le reste de l'année. Sans commission sur le séjour : le paiement revient intégralement au CE.",
"ce.kpi.commission": "de commission sur le séjour",
"ce.kpi.ceFirst": "vos membres réservent en priorité",
"ce.kpi.publicOpen": "le reste des dates rentre dans le pot",
"ce.kpi.noPaperwork": "Stripe encaisse et reverse direct",
"ce.cta": "En savoir plus pour votre CE",
"testimonials.eyebrow": "Pas de marketing",
"testimonials.title": "Ils nous l'ont dit comme ça.",
"footer.tagline": "Marketplace des carbets fluviaux de Guyane. Solidaire avec les CE locaux. Sans commission sur le séjour.",
"footer.col.discover": "Découvrir",
"footer.col.propose": "Proposer",
"footer.col.legal": "Légal",
"footer.copyright": "projet associatif numérique en Guyane.",
"season.dry": "Saison sèche",
"season.lowWater": "Étiage",
"season.wet": "Saison des pluies",
"season.dry.message": "Conditions optimales : fleuves navigables, pistes route en bon état, lever de soleil sur l'eau brûlante.",
"season.lowWater.message": "Étiage en cours : les carbets fleuve uniquement peuvent ne pas être accessibles. Filtre dispo en page recherche.",
"season.wet.message": "Pluies fréquentes : la jungle est dense et vivante, prévoir un véhicule adapté pour les carbets route+fleuve.",
"access.roadAndRiver": "🛣️ Route + fleuve",
"access.riverOnly": "🛶 Expédition fleuve",
"access.roadAndRiver.title": "Accessible par la route et par le fleuve.",
"access.riverOnly.title": "Accessible uniquement par pirogue depuis un dégrad.",
"language.switch": "Langue",
"language.fr": "Français",
"language.en": "English"
}