diff --git a/app/[locale]/about/page.tsx b/app/[locale]/about/page.tsx index 7ef3cda..5b75a39 100644 --- a/app/[locale]/about/page.tsx +++ b/app/[locale]/about/page.tsx @@ -332,9 +332,9 @@ export default function AboutPage() { Pourquoi Nous Existons -

- Notre raison d'être et la direction que nous prenons -

+

+ Notre raison d’être et la direction que nous prenons +

@@ -396,9 +396,9 @@ export default function AboutPage() {
-

- Rejoignez l'Aventure -

+

+ Rejoignez l’Aventure +

Faites partie de la révolution cloud gaming. Plus de 1500 joueurs nous font déjà confiance.

diff --git a/app/[locale]/services/page.tsx b/app/[locale]/services/page.tsx index 7521e98..f3d34f1 100644 --- a/app/[locale]/services/page.tsx +++ b/app/[locale]/services/page.tsx @@ -1,7 +1,13 @@ 'use client' -import { useMemo } from 'react' -import { useI18n } from '@/lib/i18n-simple' +import { useMemo, useState } from 'react' +import { + AnimatePresence, + LazyMotion, + domAnimation, + m, + useReducedMotion, +} from 'framer-motion' import dynamic from 'next/dynamic' import Link from 'next/link' import { useParams } from 'next/navigation' @@ -10,24 +16,19 @@ import { Cpu, HeadphonesIcon, Cloud, - ArrowRight, - TrendingUp, - Award, Rocket, Target, Users, + Sparkles, + Compass, + Layers, } from 'lucide-react' import type { LucideIcon } from 'lucide-react' import SiteHeader from '@/components/SiteHeader' -import FlipCard3D from '@/components/services/FlipCard3D' -import AnimatedCounter from '@/components/services/AnimatedCounter' -import InteractiveTimeline from '@/components/services/InteractiveTimeline' -import ParticleBackground from '@/components/services/ParticleBackground' -import GlowingCard from '@/components/services/GlowingCard' -import MorphingShape from '@/components/services/MorphingShape' +import { useI18n } from '@/lib/i18n-simple' const Footer = dynamic(() => import('@/components/Footer'), { - loading: () =>
, + loading: () =>
, ssr: false, }) @@ -57,28 +58,6 @@ type ServicesStep = { description: string } -type PillarCard = { - id: string - icon: LucideIcon - gradient: string - iconColor: string - title: string - description: string - bullets: string[] - stats: { label: string; value: string }[] - highlights: string[] -} - -type SolutionCard = { - id: string - icon: LucideIcon - gradient: string - title: string - description: string - link: string - linkLabel: string -} - type ServicesContent = { badge?: string title?: string @@ -109,30 +88,209 @@ type ServicesContent = { } } +type PillarBlueprint = { + id: string + icon: LucideIcon + label: string + accent: string + stats: { label: string; value: string }[] + defaultDescription: string + defaultBullets: string[] +} + +type SolutionBlueprint = { + id: string + icon: LucideIcon + accent: string + defaultTitle: string + defaultDescription: string + defaultLinkLabel: string + linkBuilder: (locale: string) => string +} + +const HERO_METRIC_FALLBACK: ServicesMetric[] = [ + { id: 'uptime', value: '99,9 %', label: 'Disponibilité garantie' }, + { id: 'clients', value: '120+', label: 'Clients pro accompagnés' }, + { id: 'regions', value: '8', label: 'Régions cloud actives' }, + { id: 'sla', value: '<5 min', label: 'SLA support moyen' }, +] + +const PILLAR_BLUEPRINTS: PillarBlueprint[] = [ + { + id: 'security', + icon: Shield, + label: 'Sécurité proactive', + accent: 'from-purple-500/90 to-purple-700/60', + stats: [ + { label: 'Kernel shield', value: 'Propriétaire' }, + { label: 'Audits', value: 'Quotidiens' }, + { label: 'Détection', value: '0%' }, + ], + defaultDescription: + 'Protection multi-couches, supervision anti-détection et chiffrement bout en bout.', + defaultBullets: [ + 'Surveillance continue et audits dynamiques', + 'Gestion proactive des incidents', + 'Playbooks de mitigation personnalisés', + ], + }, + { + id: 'performance', + icon: Cpu, + label: 'Performance calibrée', + accent: 'from-sky-500/90 to-indigo-700/60', + stats: [ + { label: 'GPU', value: 'RTX 4090' }, + { label: 'Latency', value: '<1 ms' }, + { label: 'Scaling', value: 'Instantané' }, + ], + defaultDescription: + 'Clusters bare-metal optimisés, pipeline CI/CD gaming et monitoring temps réel.', + defaultBullets: [ + 'Optimisation GPU frame-by-frame', + 'Auto-scaling multi-régions', + 'Benchmarks et rapports mensuels', + ], + }, + { + id: 'partnership', + icon: HeadphonesIcon, + label: 'Support dédié', + accent: 'from-emerald-500/90 to-teal-700/60', + stats: [ + { label: 'Réponse', value: '<5 min' }, + { label: 'Disponibilité', value: '24/7' }, + { label: 'Satisfaction', value: '98%' }, + ], + defaultDescription: + 'Account manager senior, escalade prioritaire et canaux privés Discord/WhatsApp.', + defaultBullets: [ + 'Veille & recommandations proactives', + 'Workshops adaptés à votre roster', + 'Documentation personnalisée', + ], + }, + { + id: 'infrastructure', + icon: Cloud, + label: 'Cloud orchestration', + accent: 'from-cyan-500/90 to-slate-700/60', + stats: [ + { label: 'Régions', value: '12+' }, + { label: 'Uptime', value: '99.99%' }, + { label: 'Déploiement', value: '<2 min' }, + ], + defaultDescription: + 'Provisionnement instantané, bascule automatique de région et sauvegardes en continu.', + defaultBullets: [ + 'Réseau 10 Gbps sécurisé', + 'Disaster recovery automatisé', + 'Intégration API PulseForge', + ], + }, +] + +const SOLUTION_BLUEPRINTS: SolutionBlueprint[] = [ + { + id: 'cloud', + icon: Rocket, + accent: 'from-blue-500/90 to-purple-500/60', + defaultTitle: 'Cloud Ops & Scaling', + defaultDescription: + 'Provisionnement automatisé, régions multiples et pipelines CI/CD prêts pour PulseForge.', + defaultLinkLabel: 'Découvrir Premium', + linkBuilder: (locale) => `/${locale}/premium`, + }, + { + id: 'competitive', + icon: Target, + accent: 'from-rose-500/90 to-orange-500/60', + defaultTitle: 'Labs Anti-Cheat', + defaultDescription: + 'Reverse engineering continu, correctifs jour zéro et protocoles d’audit conformes.', + defaultLinkLabel: 'Voir les jeux', + linkBuilder: (locale) => `/${locale}/games`, + }, + { + id: 'custom', + icon: Users, + accent: 'from-emerald-500/90 to-cyan-500/60', + defaultTitle: 'Coaching & Integrations', + defaultDescription: + 'Sessions 1:1, assistance en direct et intégrations personnalisées dans vos outils.', + defaultLinkLabel: 'Planifier un call', + linkBuilder: (locale) => `/${locale}/contact`, + }, +] + +const PROCESS_FALLBACK: ServicesStep[] = [ + { + id: 'discover', + title: 'Kick-off & audit', + description: + 'Analyse de votre roster, objectifs de performance et contraintes de sécurité.', + }, + { + id: 'prototype', + title: 'Prototype guidé', + description: + 'Instance pilote PulseForge avec profils calibrés et supervision conjointe.', + }, + { + id: 'deploy', + title: 'Déploiement orchestré', + description: + 'Activation progressive, documentation et transfert de compétences.', + }, + { + id: 'optimize', + title: 'Optimisation continue', + description: + 'Revues, benchmarks et évolution proactive selon vos retours terrain.', + }, +] + +const CONTACT_METRIC_FALLBACK: ServicesMetric[] = [ + { id: 'sla', value: '<5 min', label: 'Temps de réponse moyen' }, + { id: 'coverage', value: '24/7', label: 'Support global' }, + { id: 'satisfaction', value: '98 %', label: 'Satisfaction client' }, +] + +const heroReveal = { + hidden: { opacity: 0, y: 32 }, + show: { opacity: 1, y: 0 }, +} + +const sectionReveal = { + hidden: { opacity: 0, y: 40 }, + show: { opacity: 1, y: 0 }, +} + +const cardReveal = { + hidden: { opacity: 0, y: 24 }, + show: { opacity: 1, y: 0 }, +} + export default function ServicesPage() { const { t } = useI18n() const params = useParams() const locale = (params?.locale as string) || 'fr' const servicesContent = (t.services ?? {}) as ServicesContent + const shouldReduceMotion = useReducedMotion() - const badge = servicesContent.badge ?? 'Services Premium' - const title = servicesContent.title ?? 'Infrastructure & Sécurité' + const badge = servicesContent.badge ?? 'Services PulseForge' + const title = + servicesContent.title ?? + 'Infrastructure et sécurité professionnelles pour vos opérations gaming' const subtitle = servicesContent.subtitle ?? - 'Des services sur-mesure pour les joueurs et équipes qui exigent la perfection technique et la performance maximale.' + 'Nous combinons cloud, sécurité et coaching technique pour déployer des expériences PulseForge irréprochables.' const primaryCta = servicesContent.cta ?? 'Parler à un expert' - const heroMetricFallback: ServicesMetric[] = [ - { id: 'uptime', value: '99.9%', label: 'Uptime garanti' }, - { id: 'clients', value: '500+', label: 'Clients satisfaits' }, - { id: 'regions', value: '12', label: 'Régions globales' }, - { id: 'support', value: '24/7', label: 'Support dédié' }, - ] - const heroMetricsSource = Array.isArray(servicesContent.metrics) - ? servicesContent.metrics - : [] - const heroMetrics = heroMetricFallback.map((metric) => { - const match = heroMetricsSource.find((item) => item?.id === metric.id) + const heroMetrics = HERO_METRIC_FALLBACK.map((metric) => { + const match = Array.isArray(servicesContent.metrics) + ? servicesContent.metrics.find((item) => item?.id === metric.id) + : undefined return { ...metric, value: match?.value ?? metric.value, @@ -140,517 +298,463 @@ export default function ServicesPage() { } }) - const pillarDefaults: PillarCard[] = [ - { - id: 'security', - icon: Shield, - gradient: 'from-purple-500 via-violet-500 to-purple-600', - iconColor: 'text-purple-400', - title: 'Sécurité Maximale', - description: - 'Protection multi-couches avec supervision continue et technologies anti-détection de pointe pour une tranquillité totale.', - bullets: [ - 'Surveillance anti-cheat 24/7', - 'Kernel shield propriétaire', - 'Chiffrement E2E permanent', - ], - stats: [ - { label: 'Protection', value: 'Kernel-level' }, - { label: 'Détection', value: '0%' }, - { label: 'Uptime', value: '99.9%' }, - { label: 'Audits', value: 'Quotidiens' }, - ], - highlights: [ - 'Protection kernel-level avancée', - 'HWID spoofer intégré', - 'Bypass EAC/BE/Vanguard', - 'Stream-proof garanti', - 'Chiffrement bout en bout', - 'Monitoring en temps réel', - 'Alertes instantanées', - 'Backup automatique', - ], - }, - { - id: 'performance', - icon: Cpu, - gradient: 'from-blue-500 via-indigo-500 to-blue-600', - iconColor: 'text-blue-400', - title: 'Performance Extrême', - description: - 'Infrastructure bare-metal avec optimisation GPU frame-by-frame et pipelines CI/CD pensés pour le gaming compétitif.', - bullets: [ - 'Clusters bare-metal dédiés', - 'Optimisation GPU à la frame', - 'Monitoring de latence en direct', - ], - stats: [ - { label: 'CPU', value: 'i9-13900K' }, - { label: 'GPU', value: 'RTX 4090' }, - { label: 'RAM', value: '128GB DDR5' }, - { label: 'Latence', value: '<1ms' }, - ], - highlights: [ - 'Processeurs dernière génération', - 'GPU RTX 4090 dédiés', - 'RAM DDR5 ultra-rapide', - 'SSD NVMe Gen4', - 'Réseau 10Gbps', - 'Optimisation automatique', - 'Scaling instantané', - 'Zero downtime', - ], - }, - { - id: 'partnership', - icon: HeadphonesIcon, - gradient: 'from-emerald-500 via-teal-500 to-emerald-600', - iconColor: 'text-emerald-400', - title: 'Support Dédié', - description: - 'Account manager personnel, playbooks sur-mesure et support prioritaire sur canaux privés Discord et WhatsApp.', - bullets: [ - 'Account manager dédié', - 'Playbooks personnalisés', - 'Escalade instantanée sur Discord', - ], - stats: [ - { label: 'Réponse', value: '<5min' }, - { label: 'Disponibilité', value: '24/7' }, - { label: 'Satisfaction', value: '98%' }, - { label: 'Résolution', value: '<30min' }, - ], - highlights: [ - 'Manager dédié à votre compte', - 'Canal Discord prioritaire', - 'Support WhatsApp direct', - 'Documentation personnalisée', - 'Formations régulières', - 'Veille technologique', - 'Recommendations proactives', - 'Revues mensuelles', - ], - }, - { - id: 'infrastructure', - icon: Cloud, - gradient: 'from-cyan-500 via-sky-500 to-cyan-600', - iconColor: 'text-cyan-400', - title: 'Cloud Enterprise', - description: - 'Infrastructure cloud redondante multi-régions avec provisionnement automatisé et scaling intelligent en temps réel.', - bullets: [ - 'Multi-régions global', - 'Auto-scaling intelligent', - 'Déploiement automatisé', - ], - stats: [ - { label: 'Régions', value: '12+' }, - { label: 'Uptime', value: '99.99%' }, - { label: 'Déploiement', value: '<2min' }, - { label: 'Backup', value: 'Temps réel' }, - ], - highlights: [ - 'Présence dans 12 régions', - 'Load balancing automatique', - 'CDN global optimisé', - 'Disaster recovery', - 'Backup redondant', - 'Migration à chaud', - 'Scaling élastique', - 'Monitoring avancé', - ], - }, - { - id: 'analytics', - icon: TrendingUp, - gradient: 'from-amber-500 via-yellow-500 to-amber-600', - iconColor: 'text-amber-400', - title: 'Analytics & Insights', - description: - 'Tableaux de bord en temps réel avec métriques de performance détaillées et rapports d\'optimisation personnalisés.', - bullets: [ - 'Dashboard temps réel', - 'Métriques détaillées', - 'Rapports personnalisés', - ], - stats: [ - { label: 'Métriques', value: '50+' }, - { label: 'Refresh', value: 'Temps réel' }, - { label: 'Historique', value: '6 mois' }, - { label: 'Exports', value: 'Illimités' }, - ], - highlights: [ - 'Dashboard interactif', - 'KPIs personnalisables', - 'Alertes intelligentes', - 'Rapports automatiques', - 'Comparaisons périodiques', - 'Prédictions IA', - 'Export données brutes', - 'API complète', - ], - }, - { - id: 'compliance', - icon: Award, - gradient: 'from-pink-500 via-rose-500 to-pink-600', - iconColor: 'text-pink-400', - title: 'Conformité & Certifications', - description: - 'Infrastructure certifiée aux standards internationaux avec audits réguliers et conformité RGPD garantie.', - bullets: [ - 'Certifications ISO', - 'Conformité RGPD', - 'Audits trimestriels', - ], - stats: [ - { label: 'Certifs', value: 'ISO 27001' }, - { label: 'RGPD', value: 'Conforme' }, - { label: 'Audits', value: 'Trimestriels' }, - { label: 'SOC', value: 'Type II' }, - ], - highlights: [ - 'Certification ISO 27001', - 'SOC 2 Type II compliant', - 'RGPD full compliance', - 'Audits indépendants', - 'Documentation complète', - 'Formation équipes', - 'Politiques mises à jour', - 'Transparence totale', - ], - }, - ] - - const pillarSource = Array.isArray(servicesContent.pillars) - ? servicesContent.pillars - : [] - const pillars = pillarDefaults.map((pillar) => { - const match = pillarSource.find((item) => item?.id === pillar.id) + const pillars = useMemo(() => { + const source = Array.isArray(servicesContent.pillars) + ? servicesContent.pillars + : [] + return PILLAR_BLUEPRINTS.map((pillar) => { + const match = source.find((item) => item?.id === pillar.id) + return { + ...pillar, + title: match?.title ?? pillar.label, + description: match?.description ?? pillar.defaultDescription, + bullets: + Array.isArray(match?.bullets) && match?.bullets?.length + ? (match?.bullets as string[]) + : pillar.defaultBullets, + } + }) + }, [servicesContent.pillars]) + + const [activePillarId, setActivePillarId] = useState( + () => PILLAR_BLUEPRINTS[0]?.id ?? 'security', + ) + + const fallbackPillar = useMemo(() => { + const blueprint = PILLAR_BLUEPRINTS[0] return { - ...pillar, - title: match?.title ?? pillar.title, - description: match?.description ?? pillar.description, - bullets: - Array.isArray(match?.bullets) && match?.bullets?.length - ? (match?.bullets as string[]) - : pillar.bullets, + ...blueprint, + title: blueprint.label, + description: blueprint.defaultDescription, + bullets: blueprint.defaultBullets, } - }) + }, []) + + const activePillar = pillars.find((pillar) => pillar.id === activePillarId) + const displayedPillar = activePillar ?? fallbackPillar const pillarsHeading = { - title: servicesContent.pillarsHeading?.title ?? 'Nos Services Premium', + title: + servicesContent.pillarsHeading?.title ?? 'Des fondations pensées pour le pro', subtitle: servicesContent.pillarsHeading?.subtitle ?? - 'Une suite complète de services professionnels pour maximiser vos performances et votre sécurité.', + 'Chaque pilier combine nos briques cloud, sécurité et support pour une exécution PulseForge sans faille.', } - const solutionDefaults: SolutionCard[] = [ - { - id: 'cloud', - icon: Rocket, - gradient: 'from-sky-500 via-blue-600 to-indigo-600', - title: 'Cloud Gaming Infrastructure', - description: - 'Infrastructure cloud complète avec machines virtuelles optimisées, auto-scaling intelligent et déploiement multi-régions instantané.', - link: `/${locale}/premium`, - linkLabel: 'Découvrir Premium', - }, - { - id: 'competitive', - icon: Target, - gradient: 'from-purple-500 via-fuchsia-500 to-purple-600', - title: 'Solutions Anti-Cheat', - description: - 'Protection avancée avec reverse engineering continu, correctifs jour zéro et protocoles d\'audit pour rester indétectable sur tous les anti-cheats.', - link: `/${locale}/games`, - linkLabel: 'Voir les jeux', - }, - { - id: 'custom', - icon: Users, - gradient: 'from-emerald-500 via-teal-500 to-emerald-600', - title: 'Coaching & Intégrations', - description: - 'Accompagnement personnalisé avec sessions 1:1, assistance en direct, intégrations API sur-mesure et formation continue de vos équipes.', - link: `/${locale}/contact`, - linkLabel: 'Nous contacter', - }, - ] - - const solutionsSource = servicesContent.solutions?.items ?? [] - const solutions = solutionDefaults.map((solution) => { - const match = solutionsSource.find((item) => item?.id === solution.id) - return { - ...solution, - title: match?.title ?? solution.title, - description: match?.description ?? solution.description, - linkLabel: match?.linkLabel ?? solution.linkLabel, - } - }) + const solutions = useMemo(() => { + const source = Array.isArray(servicesContent.solutions?.items) + ? servicesContent.solutions?.items ?? [] + : [] + return SOLUTION_BLUEPRINTS.map((solution) => { + const match = source.find((item) => item?.id === solution.id) + return { + ...solution, + title: match?.title ?? solution.defaultTitle, + description: match?.description ?? solution.defaultDescription, + linkLabel: match?.linkLabel ?? solution.defaultLinkLabel, + link: solution.linkBuilder(locale), + } + }) + }, [servicesContent.solutions?.items, locale]) const solutionsHeading = { - title: servicesContent.solutions?.title ?? 'Solutions Complètes', + title: servicesContent.solutions?.title ?? 'Modules prêts à activer', subtitle: servicesContent.solutions?.subtitle ?? - 'Des modules flexibles qui s\'intègrent parfaitement à votre workflow pour un écosystème gaming complet.', + 'Composez votre stack PulseForge en sélectionnant les modules adaptés à vos besoins opérationnels.', } - const processFallback = [ - { - id: 'discover', - title: 'Découverte & Audit', - description: - 'Analyse approfondie de vos besoins, objectifs de performance et contraintes techniques pour créer une solution parfaitement adaptée.', - }, - { - id: 'prototype', - title: 'Prototype & Test', - description: - 'Mise en place d\'un environnement de test avec configurations optimisées et validation complète avant déploiement production.', - }, - { - id: 'deploy', - title: 'Déploiement Production', - description: - 'Migration progressive avec supervision continue, formation de vos équipes et documentation technique complète.', - }, - { - id: 'optimize', - title: 'Optimisation Continue', - description: - 'Monitoring permanent, revues mensuelles, ajustements proactifs et évolution de l\'infrastructure selon vos besoins.', - }, - ] - - const processSource = servicesContent.process?.steps ?? [] - const processSteps = processFallback.map((step) => { - const match = processSource.find((item) => item?.id === step.id) - return { - ...step, - title: match?.title ?? step.title, - description: match?.description ?? step.description, - } - }) + const processSteps = useMemo(() => { + const source = Array.isArray(servicesContent.process?.steps) + ? servicesContent.process?.steps ?? [] + : [] + return PROCESS_FALLBACK.map((step) => { + const match = source.find((item) => item?.id === step.id) + return { + ...step, + title: match?.title ?? step.title, + description: match?.description ?? step.description, + } + }) + }, [servicesContent.process?.steps]) const processHeading = { - title: servicesContent.process?.title ?? 'Notre Méthodologie', + title: servicesContent.process?.title ?? 'Notre méthode accompagnée', subtitle: servicesContent.process?.subtitle ?? - 'Un processus éprouvé qui garantit une intégration fluide et des résultats mesurables dès le premier jour.', + 'Un cadre en quatre phases pour intégrer PulseForge sans rupture et avec un pilotage constant.', } const contactContent = servicesContent.contact ?? {} - const contactMetricFallback: ServicesMetric[] = [ - { id: 'sla', value: '5', label: 'Temps de réponse (min)' }, - { id: 'coverage', value: '365', label: 'Jours par an' }, - { id: 'satisfaction', value: '98', label: 'Satisfaction (%)' }, - ] - - const contactMetricsSource = Array.isArray(contactContent.metrics) - ? contactContent.metrics - : [] - const contactMetrics = contactMetricFallback.map((metric) => { - const match = contactMetricsSource.find((item) => item?.id === metric.id) - return { - ...metric, - value: match?.value ?? metric.value, - label: match?.label ?? metric.label, - } - }) - - const contactNote = - contactContent.note ?? - 'Un canal prioritaire Discord & WhatsApp est activé dès la signature du contrat.' - - const contactTitle = contactContent.title ?? 'Prêt à démarrer ?' + const contactMetrics = useMemo(() => { + const source = Array.isArray(contactContent.metrics) + ? contactContent.metrics + : [] + return CONTACT_METRIC_FALLBACK.map((metric) => { + const match = source.find((item) => item?.id === metric.id) + return { + ...metric, + value: match?.value ?? metric.value, + label: match?.label ?? metric.label, + } + }) + }, [contactContent.metrics]) + + const contactTitle = + contactContent.title ?? 'Prêt à lancer votre build PulseForge ?' const contactDescription = contactContent.description ?? - 'Notre équipe vous répond sous 24h pour évaluer vos besoins et préparer un plan d\'action personnalisé.' - const contactCta = contactContent.cta ?? 'Planifier un call' + 'Nos ingénieurs vous répondent sous 24 h pour cadrer les besoins, planifier les tests et verrouiller la mise en production.' + const contactCta = contactContent.cta ?? 'Planifier un call dédié' + const contactNote = + contactContent.note ?? + 'Un canal prioritaire (Discord + WhatsApp) est ouvert dès la signature pour les escalades critiques.' return ( -
+
+ +
+
+ +
+
+
+
+ + + {badge} + + + + {title} + + + + {subtitle} + + + + + {primaryCta} + + + Explorer les offres + + +
- {/* Background Effects */} - - - - {/* Background grid */} -
-
-
- -
-
- {/* Hero Section */} -
-
- - {badge} -
- -

- - {title} - -

- -

- {subtitle} -

- - {/* Animated Counters */} -
- {heroMetrics.map((metric) => ( - - ))} -
- - - {primaryCta} - - -
- - {/* Pillars Title */} -
-

- - {pillarsHeading.title} - -

-

- {pillarsHeading.subtitle} -

-
- - {/* Flip Cards Grid */} -
- {pillars.map((pillar) => ( - - ))} -
- - {/* Solutions Section */} -
-
-

- - {solutionsHeading.title} - -

-

- {solutionsHeading.subtitle} -

+ + {heroMetrics.map((metric, index) => ( + +
+

{metric.label}

+

{metric.value}

+ + ))} + +
+
+ +
+
+ +

Pillars

+

+ {pillarsHeading.title} +

+

{pillarsHeading.subtitle}

+
+ +
+
+ {pillars.map((pillar) => { + const Icon = pillar.icon + const isActive = pillar.id === activePillarId + return ( + + ) + })} +
- {/* Glowing Cards */} -
- {solutions.map((solution) => ( - - ))} + + +
+
+
+
+

{displayedPillar.title}

+

{displayedPillar.description}

+
+
+ {displayedPillar.stats.map((stat) => ( +
+

{stat.label}

+

{stat.value}

+
+ ))} +
+
+ +
+ {displayedPillar.bullets.map((bullet, index) => ( + + + {bullet} + + ))} +
+
+ + +
-
- - {/* Process Section - Interactive Timeline */} -
-
-

- - {processHeading.title} - -

-

- {processHeading.subtitle} -

+
+ +
+
+ +

Modules

+

+ {solutionsHeading.title} +

+

{solutionsHeading.subtitle}

+
+ +
+ {solutions.map((solution, index) => { + const Icon = solution.icon + return ( + +
+
+
+ +
+

{solution.title}

+

{solution.description}

+
+ + {solution.linkLabel} + + +
+
+ + ) + })} +
- - -
- - {/* CTA Section */} -
-
-
- -

- {contactTitle} +

+ +
+
+ +

Process

+

+ {processHeading.title}

-

- {contactDescription} -

- - {/* Contact Metrics with Animation */} -
- {contactMetrics.map((metric) => ( - - ))} +

{processHeading.subtitle}

+ + +
+ {processSteps.map((step, index) => ( + +
+
+
+
+ {index + 1} +
+

{step.title}

+
+

{step.description}

+
+ + ))} +
+
+
+ +
+
+ +
+
+

Contact

+

{contactTitle}

+

{contactDescription}

+
+
+ {contactMetrics.map((metric) => ( +
+

{metric.label}

+

{metric.value}

+
+ ))} +
-

{contactNote}

- -
+
{contactCta} - - - - Voir les offres +

{contactNote}

-
+
-
-
-
- +
+ +