557 lines
39 KiB
PHP
557 lines
39 KiB
PHP
<?php
|
||
// wevia-site-builder.php
|
||
// v1.0 — 2026-04-18 — Phase B1 doctrine 108
|
||
// Génère les pages produit WEVAL rebrandées depuis template déterministe
|
||
// Respecte doctrine 108 : ReachHCP, SAP Ecosystem, suites, no client logos, no OSS names
|
||
// ZERO fake / hardcode / suppression / écrasement sans GOLD backup / régression
|
||
|
||
declare(strict_types=1);
|
||
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
// DOCTRINE 108 — forbidden terms on public pages
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
const FORBIDDEN_TERMS = [
|
||
// Client names
|
||
'Abbott', 'AbbVie', 'Johnson & Johnson', 'Johnson and Johnson',
|
||
'Servier', 'Rim Pharma', 'IQVIA', 'L\'Oréal', 'LVMH', 'Nestlé',
|
||
'Chanel', 'Carrefour', 'Intermarché', 'Michelin', 'Valeo', 'Safran',
|
||
'Vinci', 'Bombardier', 'Faiveley', 'RATP', 'Geodis', 'Deloitte', 'PwC',
|
||
'CGI', 'Sage', 'Markem', 'Givaudan', 'Lesaffre', 'Nocibe', 'Fnac',
|
||
'Pixmania', 'Shell', 'Total', 'Daher', 'Telenor', 'SNTL', 'Saham Bank',
|
||
'OCP Group', 'Reunicaa',
|
||
// Wrong partnership level
|
||
'SAP Gold', 'Gold Partner',
|
||
// OSS internal names (should be rebranded)
|
||
'Paperclip', 'DeerFlow', 'MiroFish', 'OSS Discovery', 'Cowork',
|
||
// Fake specifics
|
||
'131K+', '131000', '131 000', 'Tunisie · Maroc · Algérie',
|
||
'TN/MA/DZ', 'TN · MA · DZ',
|
||
];
|
||
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
// PRODUCTS DATA (doctrine 108 compliant, real descriptions)
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
const PRODUCTS = [
|
||
// ───── SUITE 01 · WEVIA ENTERPRISE (teal) ─────
|
||
'wevia-master' => [
|
||
'name' => 'WEVIA Master',
|
||
'tagline' => 'IA autonome propriétaire — orchestration multi-agents',
|
||
'suite' => 'WEVIA Enterprise',
|
||
'accent' => 'teal',
|
||
'badge' => 'IA Souveraine · En production',
|
||
'h1_a' => 'L\'agent qui <em>exécute</em>.',
|
||
'h1_b' => 'Pas juste répond.',
|
||
'desc' => 'Agent IA autonome propriétaire. Ne se contente pas de conseiller : scanne votre infrastructure, exécute des décisions contrôlées, apprend en continu sur votre domaine métier. Cascade multi-modèles intelligente pour combiner performance, coût maîtrisé et souveraineté des données.',
|
||
'stats' => [['Multi-model', 'Cascade intelligente'], ['Sovereign', 'EU certified'], ['<200ms', 'Latence médiane'], ['6σ', 'Qualité L99']],
|
||
'features' => [
|
||
['Orchestration multi-agents', 'Décompose les demandes complexes en sous-tâches distribuées sur agents spécialisés.'],
|
||
['Exécution contrôlée', 'Actions réelles avec journalisation, audit trail complet et gouvernance fine.'],
|
||
['Raisonnement métier', 'Fine-tuning possible sur votre domaine pour précision supérieure aux modèles génériques.'],
|
||
['Intégration système', 'API REST, webhooks, SSE streaming, hooks dans CRM, ERP, Slack, email, outils internes.'],
|
||
['Cascade souveraine', 'Combine plusieurs providers IA avec fallback intelligent, optimisation coût/qualité dynamique.'],
|
||
['Monitoring natif', 'Dashboard temps réel, métriques Six Sigma, alerting proactif sur dérive de qualité.'],
|
||
],
|
||
],
|
||
'wevia-inference' => [
|
||
'name' => 'WEVIA Inference',
|
||
'tagline' => 'GPU dédié souverain · multi-modèles',
|
||
'suite' => 'WEVIA Enterprise',
|
||
'accent' => 'teal',
|
||
'badge' => 'Infrastructure IA · Haute disponibilité',
|
||
'h1_a' => 'Inférence IA <em>sans compromis</em>',
|
||
'h1_b' => 'sur vos données.',
|
||
'desc' => 'Plateforme d\'inférence IA sur GPU dédiés, hébergée en souveraineté européenne. Déploiement multi-modèles (LLMs, vision, embeddings), API compatible OpenAI, zéro exfiltration, SLA 100%.',
|
||
'stats' => [['GPU dédié', 'A100 · H100'], ['EU Sovereign', 'Certifié'], ['API compatible', 'OpenAI spec'], ['100%', 'SLA garanti']],
|
||
'features' => [
|
||
['GPUs dédiés premium', 'A100 et H100 allouées exclusivement à vos workloads, aucun partage multi-tenant.'],
|
||
['Multi-modèles unifié', 'LLMs, vision, audio, embeddings — une seule API pour tous les cas d\'usage.'],
|
||
['API drop-in OpenAI', 'Migration depuis OpenAI en changeant uniquement l\'URL endpoint, aucun refactor code.'],
|
||
['Souveraineté stricte', 'Données et modèles hébergés en Europe, conformité RGPD, AI Act et HDS.'],
|
||
['Scaling automatique', 'Autoscaling horizontal basé sur la charge, facturation au token consommé.'],
|
||
['Fine-tuning intégré', 'Entraînement domaine métier sur vos données, versioning et rollback des modèles.'],
|
||
],
|
||
],
|
||
'projectflow' => [
|
||
'name' => 'ProjectFlow',
|
||
'tagline' => 'Orchestration projets & agents IA',
|
||
'suite' => 'WEVIA Enterprise',
|
||
'accent' => 'teal',
|
||
'badge' => 'Project Intelligence · Live',
|
||
'h1_a' => 'Vos projets,',
|
||
'h1_b' => '<em>orchestrés par IA.</em>',
|
||
'desc' => 'Plateforme de gestion de projets augmentée par agents IA. Planification, suivi d\'objectifs, orchestration d\'équipes hybrides humains-agents, reporting temps réel sur avancement et bloquants.',
|
||
'stats' => [['Agents IA', 'Spécialisés par rôle'], ['SSE', 'Streaming temps réel'], ['Kanban', '+ Agents'], ['RACI', 'Auto-généré']],
|
||
'features' => [
|
||
['Équipes hybrides', 'Humains et agents IA travaillent sur les mêmes tâches, coordination fluide.'],
|
||
['Goals & OKRs', 'Objectifs mesurables, suivi d\'avancement, alertes dérive, boucles de rétroaction.'],
|
||
['Dashboard temps réel', 'Vue directeur de l\'avancement global, des risques, des décisions en attente.'],
|
||
['Auto-RACI', 'Matrice responsabilités générée automatiquement depuis la structure du projet.'],
|
||
['Intégration native', 'Connecteurs Jira, GitHub, Slack, Gmail, Teams — pas de silo d\'information.'],
|
||
['Audit trail', 'Traçabilité complète des décisions, idéal pour environnements réglementés.'],
|
||
],
|
||
],
|
||
'researchflow' => [
|
||
'name' => 'ResearchFlow',
|
||
'tagline' => 'Recherche multi-agents approfondie',
|
||
'suite' => 'WEVIA Enterprise',
|
||
'accent' => 'teal',
|
||
'badge' => 'Research Intelligence · Live',
|
||
'h1_a' => 'La recherche approfondie,',
|
||
'h1_b' => '<em>automatisée.</em>',
|
||
'desc' => 'Moteur de recherche multi-agents. Décompose une question complexe en sous-requêtes, explore sources publiques et internes, synthétise un rapport structuré avec citations vérifiables.',
|
||
'stats' => [['Multi-agents', 'Spécialisés'], ['Sources', 'Web + interne'], ['Citations', 'Vérifiables'], ['Markdown', 'Structuré']],
|
||
'features' => [
|
||
['Décomposition automatique', 'Une question complexe devient un arbre de sous-questions explorées en parallèle.'],
|
||
['Sources internes & web', 'Combine votre base documentaire privée avec les sources publiques crédibles.'],
|
||
['Citations vérifiables', 'Chaque affirmation liée à sa source, lien direct, extraction du passage original.'],
|
||
['Rapport Markdown', 'Livrable structuré prêt à l\'emploi : exec summary, détails, annexes, bibliographie.'],
|
||
['Vérification croisée', 'Triangulation automatique des informations entre sources pour fiabilité.'],
|
||
['Export multi-format', 'PDF, Word, Notion, Confluence — intégration dans vos flux existants.'],
|
||
],
|
||
],
|
||
'boardflow' => [
|
||
'name' => 'BoardFlow',
|
||
'tagline' => 'Whiteboard collaboratif intelligent',
|
||
'suite' => 'WEVIA Enterprise',
|
||
'accent' => 'teal',
|
||
'badge' => 'Collaboration · Live',
|
||
'h1_a' => 'Le whiteboard',
|
||
'h1_b' => '<em>qui pense avec vous.</em>',
|
||
'desc' => 'Tableau collaboratif visuel augmenté par IA. Brainstorming, architecture, mind-mapping, process design. L\'IA suggère, structure, reformule, détecte les angles morts en temps réel.',
|
||
'stats' => [['Temps réel', 'Collaboration multi-user'], ['IA intégrée', 'Suggestions contextuelles'], ['Templates', 'Design thinking'], ['Export', 'Multi-format']],
|
||
'features' => [
|
||
['Canvas infini', 'Espace visuel illimité pour sketches, diagrammes, notes, connexions, structures.'],
|
||
['Co-création IA', 'L\'agent propose, restructure, consolide, détecte les incohérences en temps réel.'],
|
||
['Templates métier', 'Bibliothèque de patterns : design thinking, BPMN, architecture, product canvas.'],
|
||
['Présence multi-user', 'Curseurs temps réel, voix/vidéo embarquée, mode focus ou revue synchrone.'],
|
||
['Versioning', 'Historique complet des évolutions, fork et merge de branches créatives.'],
|
||
['Intégration outils', 'Import depuis Figma, Lucidchart, Miro, Visio ; export multi-format.'],
|
||
],
|
||
],
|
||
'stackscan' => [
|
||
'name' => 'StackScan',
|
||
'tagline' => 'Audit & inventaire OSS entreprise',
|
||
'suite' => 'WEVIA Enterprise',
|
||
'accent' => 'teal',
|
||
'badge' => 'Open Source Discovery · Live',
|
||
'h1_a' => 'Votre stack open source,',
|
||
'h1_b' => '<em>en pleine lumière.</em>',
|
||
'desc' => 'Scanner et cartographe de votre écosystème open source. Détecte dépendances, licences, vulnérabilités, versions obsolètes. Recommandations de remédiation priorisées par impact et effort.',
|
||
'stats' => [['Licences', 'SPDX complet'], ['CVE', 'Temps réel'], ['SBOM', 'CycloneDX + SPDX'], ['Priorisation', 'Impact × effort']],
|
||
'features' => [
|
||
['SBOM automatique', 'Génération Software Bill of Materials au format CycloneDX ou SPDX, exports continus.'],
|
||
['Licences & conformité', 'Détection de toutes licences, alertes sur incompatibilités et contraintes juridiques.'],
|
||
['CVE temps réel', 'Scanning continu des vulnérabilités, alertes proactives, corrélation avec votre contexte.'],
|
||
['Priorisation intelligente', 'Impact business × effort de remédiation = file d\'attente d\'actions claire.'],
|
||
['Intégration CI/CD', 'Hooks GitHub Actions, GitLab CI, Jenkins — bloque les déploiements non conformes.'],
|
||
['Dashboard exécutif', 'Vue directeur du risque OSS, tendances, score santé de chaque composant métier.'],
|
||
],
|
||
],
|
||
'wevia-desk' => [
|
||
'name' => 'WEVIA Desk',
|
||
'tagline' => 'Automatisation bureautique par IA',
|
||
'suite' => 'WEVIA Enterprise',
|
||
'accent' => 'teal',
|
||
'badge' => 'Desktop Automation · Live',
|
||
'h1_a' => 'L\'agent qui pilote',
|
||
'h1_b' => '<em>votre poste de travail.</em>',
|
||
'desc' => 'Agent IA desktop. Automatise tâches répétitives : tri d\'emails, extraction de données, remplissage de formulaires, génération de livrables. Contrôle des applications natives via API ou vision.',
|
||
'stats' => [['Native apps', 'Contrôle direct'], ['Vision IA', 'OCR + reconnaissance'], ['Workflows', 'Low-code'], ['Audit', 'Log complet']],
|
||
'features' => [
|
||
['Contrôle natif', 'Pilote Excel, Word, Outlook, navigateur, applications métier via API ou automation visuelle.'],
|
||
['Vision IA intégrée', 'OCR et reconnaissance visuelle pour interagir avec interfaces legacy sans API.'],
|
||
['Workflows low-code', 'Éditeur visuel pour orchestrer des séquences complexes sans savoir coder.'],
|
||
['Déclencheurs contextuels', 'Actions lancées sur email reçu, fichier déposé, heure, événement calendrier.'],
|
||
['Mode supervisé', 'Validation humaine requise pour actions sensibles, audit trail exhaustif.'],
|
||
['Déploiement groupé', 'Rollout sur parc de postes avec gouvernance centrale, policies par rôle.'],
|
||
],
|
||
],
|
||
// ───── SUITE 03 · WEVAL PHARMA CLOUD (coral) ─────
|
||
'reachhcp' => [
|
||
'name' => 'ReachHCP',
|
||
'tagline' => 'Base HCP mondiale · consent-based',
|
||
'suite' => 'WEVAL Pharma Cloud',
|
||
'accent' => 'coral',
|
||
'badge' => 'Healthcare Intelligence · Live',
|
||
'h1_a' => 'Les professionnels de santé,',
|
||
'h1_b' => '<em>atteints dans les règles.</em>',
|
||
'desc' => 'Base de données de professionnels de santé vérifiés, consent-based, couverture mondiale. Segmentation fine par spécialité, zone, typologie d\'exercice. Conformité RGPD, HDS, exports auditables.',
|
||
'stats' => [['Mondial', 'Multi-continents'], ['Consent', 'Opt-in vérifié'], ['RGPD', '+ HDS'], ['Update', 'Continu']],
|
||
'features' => [
|
||
['Couverture mondiale', 'Europe, Amériques, MENA, Asie — spécialistes hospitaliers et libéraux, tous secteurs.'],
|
||
['Consent-based strict', 'Opt-in vérifié source, traçabilité complète, retrait à tout moment, conformité maximale.'],
|
||
['Segmentation fine', 'Spécialité, sous-spécialité, zone géographique, typologie d\'exercice, affiliation.'],
|
||
['Enrichissement continu', 'Mises à jour en continu, détection automatique des changements, déduplication ML.'],
|
||
['Exports auditables', 'Logs complets de chaque extraction, justification du consent, preuves horodatées.'],
|
||
['API temps réel', 'REST et GraphQL pour intégration CRM, automation marketing, analytics.'],
|
||
],
|
||
],
|
||
'campaign-studio' => [
|
||
'name' => 'Campaign Studio',
|
||
'tagline' => 'Création & orchestration campagnes pharma',
|
||
'suite' => 'WEVAL Pharma Cloud',
|
||
'accent' => 'coral',
|
||
'badge' => 'Pharma Campaigns · Live',
|
||
'h1_a' => 'La campagne omnicanale,',
|
||
'h1_b' => '<em>compliant by design.</em>',
|
||
'desc' => 'Studio de création et orchestration de campagnes pharma. Assets conformes (validation médicale embarquée), multicanal (email, print, meetings, digital), tracking conforme, reporting exécutif.',
|
||
'stats' => [['Multicanal', 'Email · Print · Live'], ['Validation', 'Médicale auto'], ['Compliance', 'Track complet'], ['ROI', 'Vue exec']],
|
||
'features' => [
|
||
['Studio de création', 'Éditeur visuel avec bibliothèque d\'assets, templates validés, versioning complet.'],
|
||
['Validation médicale', 'Workflow de relecture obligatoire, audit trail, signature électronique des MRL.'],
|
||
['Orchestration multicanal', 'Une séquence = email + courrier + meeting + push — cadencement intelligent.'],
|
||
['Tracking compliant', 'Attribution fine conforme RGPD, pas de cookies tiers, pixels propriétaires.'],
|
||
['Dashboard ROI', 'Vue exécutive par campagne, par produit, par territoire, par spécialité.'],
|
||
['A/B testing rigoureux', 'Plans d\'expérience statistiquement signifiants, significance testing intégré.'],
|
||
],
|
||
],
|
||
'consent-manager' => [
|
||
'name' => 'Consent Manager',
|
||
'tagline' => 'Gestion du consentement B2B healthcare',
|
||
'suite' => 'WEVAL Pharma Cloud',
|
||
'accent' => 'coral',
|
||
'badge' => 'B2B Consent · Live',
|
||
'h1_a' => 'Le consentement professionnel,',
|
||
'h1_b' => '<em>géré comme un asset.</em>',
|
||
'desc' => 'Plateforme de gestion du consentement B2B pour les interactions avec professionnels de santé. Collecte, stockage horodaté, retrait, audit, preuve légale. Conformité RGPD, LPD, LGPD, CCPA.',
|
||
'stats' => [['Multi-juridictions', 'RGPD · LPD · LGPD'], ['Preuve', 'Horodatée'], ['Retrait', 'Un clic'], ['Audit', 'Exports complets']],
|
||
'features' => [
|
||
['Collecte multi-canal', 'Formulaires web, mobile, print avec QR, signature électronique, validation téléphonique.'],
|
||
['Stockage horodaté', 'Chaque consent ou refus daté, sourcé, signé — preuve juridique opposable.'],
|
||
['Retrait en un clic', 'Liens de désinscription dans chaque communication, propagation immédiate aux systèmes.'],
|
||
['Audit trail complet', 'Qui, quoi, quand, depuis où — exports complets à la demande d\'un régulateur.'],
|
||
['Conformité multi-juridictions', 'RGPD européen, LPD suisse, LGPD brésilien, CCPA californien, mises à jour continues.'],
|
||
['API temps réel', 'Hooks vers CRM, marketing automation, data warehouse — synchro sub-seconde.'],
|
||
],
|
||
],
|
||
];
|
||
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
// HTML TEMPLATE (doctrine 108 compliant)
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
function get_template(): string {
|
||
return <<<'HTML'
|
||
<!DOCTYPE html>
|
||
<html lang="fr"><head>
|
||
<link rel="icon" href="/favicon.ico" type="image/x-icon">
|
||
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
||
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||
<title>{{NAME}} — {{TAGLINE}} | WEVAL Consulting</title>
|
||
<meta name="description" content="{{NAME}} — {{DESC_SHORT}} Part of {{SUITE}} suite.">
|
||
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=Outfit:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
||
<style>:root{--bg:#05080f;--s:#0c1222;--s2:#111830;--teal:#00c9a7;--purple:#7c5cfc;--gold:#f0c674;--coral:#ff6b6b;--blue:#4ea8de;--silver:#7a8ba5;--white:#edf2f7;--dim:#8a99b5;--a:{{ACCENT_HEX}};--a15:{{ACCENT_15}};--b:{{ACCENT_08}}}*{margin:0;padding:0;box-sizing:border-box}body{font-family:'Outfit',sans-serif;background:var(--bg);color:var(--white);overflow-x:hidden;-webkit-font-smoothing:antialiased}body::before{content:'';position:fixed;inset:0;background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.025'/%3E%3C/svg%3E");pointer-events:none;z-index:1000}nav{position:fixed;top:0;width:100%;padding:1rem 4%;display:flex;justify-content:space-between;align-items:center;z-index:100;backdrop-filter:blur(24px);background:rgba(5,8,15,.82);border-bottom:1px solid var(--b)}.logo{font-weight:800;font-size:1.35rem;letter-spacing:-.035em;display:flex;align-items:center;gap:.5rem}.logo-dot{width:10px;height:10px;border-radius:50%;background:var(--a);box-shadow:0 0 18px var(--a)}.nav-r{display:flex;gap:1.8rem;align-items:center}.nav-r a{color:var(--silver);text-decoration:none;font-size:.84rem;font-weight:500;transition:color .25s}.nav-r a:hover{color:var(--white)}.btn-n{background:var(--a);color:var(--bg);padding:.55rem 1.3rem;border-radius:7px;font-weight:700;font-size:.82rem;text-decoration:none;transition:transform .2s}.btn-n:hover{transform:translateY(-1px)}.hero{min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:8rem 4% 4rem;position:relative;overflow:hidden}.hero::after{content:'';position:absolute;top:8%;left:50%;transform:translateX(-50%);width:900px;height:900px;background:radial-gradient(circle,{{ACCENT_RAD}} 0%,transparent 70%);border-radius:50%;pointer-events:none}.badge{display:inline-flex;align-items:center;gap:.5rem;background:var(--a15);border:1px solid var(--b);border-radius:100px;padding:.4rem 1.1rem;font-size:.74rem;font-weight:600;color:var(--a);margin-bottom:2rem;font-family:'Space Mono',monospace;letter-spacing:.05em;position:relative}.badge::before{content:'';width:6px;height:6px;background:var(--a);border-radius:50%;animation:pulse 1.8s infinite}@keyframes pulse{0%,100%{opacity:1}50%{opacity:.3}}h1{font-size:clamp(2.4rem,5vw,4rem);font-weight:800;line-height:1.05;letter-spacing:-.04em;max-width:900px;margin-bottom:1.4rem;position:relative}h1 em{font-style:normal;color:var(--a)}.sub{font-size:1.05rem;color:var(--silver);max-width:680px;line-height:1.65;margin-bottom:2.5rem;font-weight:300;position:relative}.btns{display:flex;gap:1rem;flex-wrap:wrap;justify-content:center;position:relative}.btn-p{background:var(--a);color:var(--bg);padding:.9rem 2rem;border-radius:8px;font-weight:700;font-size:.88rem;text-decoration:none;transition:all .25s;display:inline-flex;align-items:center;gap:.4rem}.btn-p:hover{transform:translateY(-2px)}.btn-o{background:transparent;color:var(--white);padding:.9rem 2rem;border-radius:8px;font-weight:500;font-size:.88rem;text-decoration:none;border:1px solid rgba(237,242,247,.15);transition:all .25s;display:inline-flex;align-items:center;gap:.4rem}.btn-o:hover{border-color:var(--a);color:var(--a)}.suite-chip{display:inline-flex;align-items:center;gap:.5rem;margin-top:1.4rem;padding:.32rem .85rem;background:rgba(255,255,255,.03);border:1px solid var(--b);border-radius:100px;font-size:.72rem;color:var(--silver);font-family:'Space Mono',monospace;font-weight:600;letter-spacing:.04em;position:relative;text-decoration:none;transition:all .25s}.suite-chip:hover{color:var(--a);border-color:var(--a)}.sec{padding:5rem 4%;max-width:1200px;margin:0 auto}.stag{font-family:'Space Mono',monospace;font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.22em;color:var(--a);margin-bottom:1rem;display:inline-block}h2{font-size:clamp(1.8rem,2.8vw,2.4rem);font-weight:800;letter-spacing:-.032em;line-height:1.1;margin-bottom:.8rem;max-width:680px}h2 em{font-style:normal;color:var(--a)}.sd{color:var(--silver);font-size:1rem;line-height:1.65;max-width:580px;margin-bottom:3rem;font-weight:300}.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:0;background:var(--s);border:1px solid var(--b);border-radius:14px;overflow:hidden;margin:2rem 0 3rem}.stat{padding:1.4rem 1rem;text-align:center;border-right:1px solid var(--b)}.stat:last-child{border-right:none}.stat-n{font-family:'Space Mono',monospace;font-size:1.3rem;font-weight:700;color:var(--a);line-height:1}.stat-l{font-size:.7rem;color:var(--silver);margin-top:.45rem;text-transform:uppercase;letter-spacing:.1em;font-weight:500}.g3{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;margin-top:1.5rem}.fcd{background:var(--s);border:1px solid var(--b);border-radius:14px;padding:1.6rem;transition:all .3s;position:relative;overflow:hidden}.fcd::before{content:'';position:absolute;top:0;left:0;width:3px;height:100%;background:var(--a);opacity:0;transition:opacity .3s}.fcd:hover{border-color:var(--a);transform:translateY(-3px)}.fcd:hover::before{opacity:1}.fcd h3{font-size:1rem;font-weight:700;margin-bottom:.5rem;letter-spacing:-.01em}.fcd p{font-size:.85rem;color:var(--silver);line-height:1.6;font-weight:300}.suite-box{background:var(--s);border:1px solid var(--b);border-radius:16px;padding:2rem;display:grid;grid-template-columns:1.2fr 0.8fr;gap:2rem;align-items:center;margin-top:2rem}.suite-box-l h3{font-size:1.3rem;font-weight:700;margin-bottom:.6rem;letter-spacing:-.02em}.suite-box-l p{color:var(--silver);font-size:.92rem;line-height:1.6;font-weight:300;margin-bottom:1rem}.suite-box-r{display:flex;flex-wrap:wrap;gap:.35rem}.apptag{background:rgba(0,0,0,.25);border:1px solid var(--b);border-radius:5px;padding:.28rem .65rem;font-size:.72rem;color:var(--white);font-family:'Space Mono',monospace;font-weight:500}.apptag.self{background:var(--a15);color:var(--a);border-color:var(--a)}.cta{text-align:center;padding:4rem 2rem;margin:2rem 4%;background:linear-gradient(135deg,var(--s),rgba(0,0,0,.2));border:1px solid var(--b);border-radius:22px;position:relative;overflow:hidden}.cta::before{content:'';position:absolute;inset:0;background:radial-gradient(circle at 50% 0%,{{ACCENT_RAD}},transparent 60%);pointer-events:none}.cta h2{margin:0 auto .8rem;position:relative}.cta p{color:var(--silver);max-width:540px;margin:0 auto 2rem;font-weight:300;position:relative}.cta .btns{position:relative}footer{padding:2.5rem 4% 1.5rem;max-width:1200px;margin:2rem auto 0;border-top:1px solid rgba(255,255,255,.05)}.foot-t{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem;flex-wrap:wrap;gap:1rem}.foot-t .logo{font-size:1.1rem}.foot-links{display:flex;gap:1.5rem;font-size:.82rem}.foot-links a{color:var(--silver);text-decoration:none;transition:color .2s}.foot-links a:hover{color:var(--a)}.foot-b{font-size:.72rem;color:var(--dim);font-family:'Space Mono',monospace;letter-spacing:.05em}@media(max-width:900px){h1{font-size:2.2rem}.stats{grid-template-columns:1fr 1fr}.stat:nth-child(odd){border-right:1px solid var(--b)}.stat:nth-child(even){border-right:none}.stat{border-bottom:1px solid var(--b)}.g3{grid-template-columns:1fr}.suite-box{grid-template-columns:1fr;padding:1.5rem}.nav-r a:not(.btn-n){display:none}}</style>
|
||
<style>@media all{.in-iframe nav{display:none!important}.in-iframe .hero{padding-top:3rem!important;min-height:auto!important}.in-iframe footer{display:none!important}.in-iframe .cta{display:none!important}}</style>
|
||
<script>if(window!==window.top)document.documentElement.classList.add('in-iframe');</script>
|
||
<link rel="canonical" href="https://weval-consulting.com/products/{{SLUG}}.html">
|
||
<meta property="og:title" content="{{NAME}} — {{TAGLINE}}">
|
||
<meta property="og:description" content="{{NAME}} — {{DESC_SHORT}}">
|
||
<meta property="og:url" content="https://weval-consulting.com/products/{{SLUG}}.html">
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:site_name" content="WEVAL Consulting">
|
||
<meta property="og:image" content="https://weval-consulting.com/assets/logo-weval-png-DChrMGao.png">
|
||
<meta name="twitter:card" content="summary">
|
||
<meta name="twitter:title" content="{{NAME}} — {{TAGLINE}}">
|
||
<meta name="twitter:description" content="{{NAME}} — {{DESC_SHORT}}">
|
||
</head><body>
|
||
|
||
<nav>
|
||
<div class="logo"><span class="logo-dot"></span>{{NAME}}<span style="color:var(--a)">.</span></div>
|
||
<div class="nav-r">
|
||
<a href="/">Accueil</a>
|
||
<a href="/products/">Produits</a>
|
||
<a href="/marketplace">Marketplace</a>
|
||
<a href="#cta" class="btn-n">Demander une démo →</a>
|
||
</div>
|
||
</nav>
|
||
|
||
<section class="hero">
|
||
<div class="badge">{{BADGE}}</div>
|
||
<h1>{{H1_A}}<br>{{H1_B}}</h1>
|
||
<p class="sub">{{DESC}}</p>
|
||
<div class="btns">
|
||
<a href="#cta" class="btn-p">Demander une démo →</a>
|
||
<a href="/solutions/{{SUITE_SLUG}}.html" class="btn-o">Explorer la suite</a>
|
||
</div>
|
||
<a href="/solutions/{{SUITE_SLUG}}.html" class="suite-chip">▸ Composant de la suite {{SUITE}}</a>
|
||
</section>
|
||
|
||
<section class="sec">
|
||
<div class="stag">// Métriques clés</div>
|
||
<h2>La <em>performance</em>, chiffrée.</h2>
|
||
<div class="stats">{{STATS_HTML}}</div>
|
||
</section>
|
||
|
||
<section class="sec">
|
||
<div class="stag">// Capacités</div>
|
||
<h2>Ce que {{NAME}} <em>fait pour vous.</em></h2>
|
||
<p class="sd">Fonctionnalités clés, livrées en production. Chaque capacité est éprouvée en conditions réelles et maintenue sous standard Six Sigma L99.</p>
|
||
<div class="g3">{{FEATURES_HTML}}</div>
|
||
</section>
|
||
|
||
<section class="sec">
|
||
<div class="stag">// Écosystème</div>
|
||
<h2>Intégré dans <em>{{SUITE}}.</em></h2>
|
||
<p class="sd">{{NAME}} s'inscrit dans la suite {{SUITE}}, conçue pour l'interopérabilité. Chaque application de la suite communique nativement, partage données et événements, amplifie la valeur des autres.</p>
|
||
<div class="suite-box">
|
||
<div class="suite-box-l">
|
||
<h3>Suite {{SUITE}}</h3>
|
||
<p>{{SUITE_DESC}}</p>
|
||
<a href="/solutions/{{SUITE_SLUG}}.html" class="btn-o" style="padding:.6rem 1.2rem;font-size:.8rem">Voir la suite complète →</a>
|
||
</div>
|
||
<div class="suite-box-r">{{SIBLING_TAGS}}</div>
|
||
</div>
|
||
</section>
|
||
|
||
<div class="cta" id="cta">
|
||
<div class="stag" style="text-align:center;display:block">// Commencer</div>
|
||
<h2>Prêt à <em>essayer {{NAME}}</em> ?</h2>
|
||
<p>Démonstration personnalisée sur vos données. Diagnostic cas d'usage, scoping technique, proposition de déploiement en 45 minutes.</p>
|
||
<div class="btns">
|
||
<a href="/#contact" class="btn-p">Réserver une démo →</a>
|
||
<a href="/marketplace" class="btn-o">Voir le catalogue complet</a>
|
||
</div>
|
||
</div>
|
||
|
||
<footer>
|
||
<div class="foot-t">
|
||
<div class="logo"><span class="logo-dot"></span>WEVAL<span style="color:var(--a)">.</span></div>
|
||
<div class="foot-links">
|
||
<a href="/">Accueil</a>
|
||
<a href="/products/">Produits</a>
|
||
<a href="/marketplace">Marketplace</a>
|
||
<a href="/#contact">Contact</a>
|
||
</div>
|
||
</div>
|
||
<div class="foot-b">© 2026 WEVAL Consulting · Cabinet de conseil & éditeur IA souveraine · Partenaire Écosystème SAP · Huawei Cloud Certified</div>
|
||
</footer>
|
||
|
||
</body></html>
|
||
HTML;
|
||
}
|
||
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
// SUITE DEFINITIONS (doctrine 108)
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
const SUITES = [
|
||
'WEVIA Enterprise' => [
|
||
'slug' => 'wevia-enterprise',
|
||
'desc' => 'L\'écosystème d\'IA souveraine propriétaire WEVAL. Agent autonome, inférence GPU dédiée, orchestration multi-agents, whiteboard collaboratif, audit de stack, automatisation desktop — une stack complète, interopérable, souveraine.',
|
||
'siblings' => ['WEVIA Master', 'WEVIA Inference', 'WEVIA Life', 'WEVIA White-Label', 'ProjectFlow', 'ResearchFlow', 'BoardFlow', 'Blade AI', 'StackScan', 'WEVIA Desk'],
|
||
],
|
||
'WEVAL Pharma Cloud' => [
|
||
'slug' => 'pharma-cloud',
|
||
'desc' => 'Suite dédiée aux sciences de la vie et à l\'industrie pharmaceutique. Base HCP mondiale consent-based, CRM pharma, studio de campagnes compliant, gestion du consentement, dashboard exécutif.',
|
||
'siblings' => ['ReachHCP', 'ReachHCP API', 'Healthcare CRM', 'Campaign Studio', 'HCP Dashboard', 'Consent Manager'],
|
||
],
|
||
];
|
||
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
// ACCENT COLORS
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
const ACCENTS = [
|
||
'teal' => ['hex' => '#00c9a7', 'rad' => 'rgba(0,201,167,.08)', 'a15' => 'rgba(0,201,167,.12)', 'a08' => 'rgba(0,201,167,.08)'],
|
||
'purple' => ['hex' => '#7c5cfc', 'rad' => 'rgba(124,92,252,.08)', 'a15' => 'rgba(124,92,252,.12)', 'a08' => 'rgba(124,92,252,.08)'],
|
||
'gold' => ['hex' => '#f0c674', 'rad' => 'rgba(240,198,116,.06)','a15' => 'rgba(240,198,116,.15)','a08' => 'rgba(240,198,116,.08)'],
|
||
'coral' => ['hex' => '#ff6b6b', 'rad' => 'rgba(255,107,107,.06)','a15' => 'rgba(255,107,107,.12)','a08' => 'rgba(255,107,107,.08)'],
|
||
];
|
||
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
// BUILDER
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
function build_page(string $slug): array {
|
||
if (!isset(PRODUCTS[$slug])) {
|
||
return ['ok' => false, 'slug' => $slug, 'error' => 'Unknown slug'];
|
||
}
|
||
$p = PRODUCTS[$slug];
|
||
$suite_name = $p['suite'];
|
||
if (!isset(SUITES[$suite_name])) {
|
||
return ['ok' => false, 'slug' => $slug, 'error' => 'Unknown suite: ' . $suite_name];
|
||
}
|
||
$suite = SUITES[$suite_name];
|
||
$accent = ACCENTS[$p['accent']];
|
||
|
||
// Build stats HTML
|
||
$stats_html = '';
|
||
foreach ($p['stats'] as [$v, $l]) {
|
||
$stats_html .= sprintf('<div class="stat"><div class="stat-n">%s</div><div class="stat-l">%s</div></div>',
|
||
htmlspecialchars($v), htmlspecialchars($l));
|
||
}
|
||
|
||
// Build features HTML
|
||
$features_html = '';
|
||
foreach ($p['features'] as [$title, $text]) {
|
||
$features_html .= sprintf('<div class="fcd"><h3>%s</h3><p>%s</p></div>',
|
||
htmlspecialchars($title), htmlspecialchars($text));
|
||
}
|
||
|
||
// Build sibling tags
|
||
$sibling_tags = '';
|
||
foreach ($suite['siblings'] as $sib) {
|
||
$cls = ($sib === $p['name']) ? 'apptag self' : 'apptag';
|
||
$sibling_tags .= sprintf('<span class="%s">%s</span>', $cls, htmlspecialchars($sib));
|
||
}
|
||
|
||
// Short desc for meta (first 140 chars)
|
||
$desc_short = mb_substr(strip_tags($p['desc']), 0, 140);
|
||
|
||
// Substitute
|
||
$html = get_template();
|
||
$vars = [
|
||
'{{SLUG}}' => $slug,
|
||
'{{NAME}}' => $p['name'],
|
||
'{{TAGLINE}}' => $p['tagline'],
|
||
'{{BADGE}}' => $p['badge'],
|
||
'{{H1_A}}' => $p['h1_a'],
|
||
'{{H1_B}}' => $p['h1_b'],
|
||
'{{DESC}}' => $p['desc'],
|
||
'{{DESC_SHORT}}' => $desc_short,
|
||
'{{SUITE}}' => $suite_name,
|
||
'{{SUITE_SLUG}}' => $suite['slug'],
|
||
'{{SUITE_DESC}}' => $suite['desc'],
|
||
'{{STATS_HTML}}' => $stats_html,
|
||
'{{FEATURES_HTML}}' => $features_html,
|
||
'{{SIBLING_TAGS}}'=> $sibling_tags,
|
||
'{{ACCENT_HEX}}' => $accent['hex'],
|
||
'{{ACCENT_RAD}}' => $accent['rad'],
|
||
'{{ACCENT_15}}' => $accent['a15'],
|
||
'{{ACCENT_08}}' => $accent['a08'],
|
||
];
|
||
$html = strtr($html, $vars);
|
||
|
||
// DOCTRINE 108 VALIDATION — forbidden terms (word-boundary, case-sensitive for company names)
|
||
foreach (FORBIDDEN_TERMS as $term) {
|
||
// Use word boundary + case-sensitive regex to avoid false positives (sage in usage, total in lowercase)
|
||
$pattern = '/\b' . preg_quote($term, '/') . '\b/';
|
||
if (preg_match($pattern, $html)) {
|
||
return ['ok' => false, 'slug' => $slug, 'error' => "Forbidden term: $term"];
|
||
}
|
||
}
|
||
|
||
// Basic HTML validation
|
||
if (!str_contains($html, '<!DOCTYPE html>')) {
|
||
return ['ok' => false, 'slug' => $slug, 'error' => 'Missing DOCTYPE'];
|
||
}
|
||
if (!str_contains($html, '</html>')) {
|
||
return ['ok' => false, 'slug' => $slug, 'error' => 'Missing closing html'];
|
||
}
|
||
|
||
// Write
|
||
$target = "/var/www/html/products/{$slug}.html";
|
||
if (file_exists($target)) {
|
||
// GOLD backup before overwrite
|
||
$gold_dir = '/opt/wevads/vault/gold-site-pages-' . date('Ymd');
|
||
if (!is_dir($gold_dir)) @mkdir($gold_dir, 0755, true);
|
||
@copy($target, $gold_dir . "/{$slug}-" . date('His') . '.html');
|
||
return ['ok' => false, 'slug' => $slug, 'error' => 'File exists — zero écrasement doctrine'];
|
||
}
|
||
$ok = @file_put_contents($target, $html);
|
||
if ($ok === false) {
|
||
return ['ok' => false, 'slug' => $slug, 'error' => 'Write failed'];
|
||
}
|
||
|
||
return ['ok' => true, 'slug' => $slug, 'file' => $target, 'bytes' => strlen($html), 'features' => count($p['features'])];
|
||
}
|
||
|
||
function scan_forbidden(string $dir = '/var/www/html'): array {
|
||
$hits = [];
|
||
$exts = ['html', 'htm'];
|
||
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS));
|
||
foreach ($rii as $f) {
|
||
if (!in_array(strtolower($f->getExtension()), $exts, true)) continue;
|
||
$path = $f->getPathname();
|
||
if (str_contains($path, '/node_modules/') || str_contains($path, '/.git/')) continue;
|
||
$content = @file_get_contents($path);
|
||
if ($content === false) continue;
|
||
foreach (['SAP Gold', 'Gold Partner'] as $t) {
|
||
$pattern = '/\b' . preg_quote($t, '/') . '\b/';
|
||
if (preg_match($pattern, $content)) {
|
||
$hits[] = ['file' => $path, 'term' => $t];
|
||
}
|
||
}
|
||
}
|
||
return $hits;
|
||
}
|
||
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
// CLI ENTRY
|
||
// ═══════════════════════════════════════════════════════════════════
|
||
if (PHP_SAPI !== 'cli') {
|
||
http_response_code(403);
|
||
echo "CLI only";
|
||
exit;
|
||
}
|
||
|
||
$action = $argv[1] ?? 'help';
|
||
|
||
switch ($action) {
|
||
case 'build':
|
||
$slug = $argv[2] ?? null;
|
||
if (!$slug) { echo "Usage: build SLUG\n"; exit(1); }
|
||
$r = build_page($slug);
|
||
echo json_encode($r, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . "\n";
|
||
break;
|
||
|
||
case 'build_all':
|
||
$results = [];
|
||
$ok = 0; $fail = 0;
|
||
foreach (array_keys(PRODUCTS) as $slug) {
|
||
$r = build_page($slug);
|
||
$results[] = $r;
|
||
if ($r['ok']) { $ok++; } else { $fail++; }
|
||
echo sprintf("[%s] %-20s %s\n",
|
||
$r['ok'] ? 'OK' : 'XX',
|
||
$slug,
|
||
$r['ok'] ? ($r['bytes'] . 'B, ' . $r['features'] . ' features') : $r['error']);
|
||
}
|
||
echo sprintf("\n=== %d OK · %d FAIL ===\n", $ok, $fail);
|
||
break;
|
||
|
||
case 'list':
|
||
foreach (PRODUCTS as $s => $p) {
|
||
echo sprintf("%-20s | %-25s | %s\n", $s, $p['suite'], $p['tagline']);
|
||
}
|
||
break;
|
||
|
||
case 'scan_forbidden':
|
||
$hits = scan_forbidden('/var/www/html');
|
||
if (!$hits) { echo "Aucune occurrence interdite trouvée.\n"; exit(0); }
|
||
foreach ($hits as $h) {
|
||
echo sprintf("FOUND: %s in %s\n", $h['term'], $h['file']);
|
||
}
|
||
echo sprintf("\n=== %d fichiers à nettoyer ===\n", count($hits));
|
||
break;
|
||
|
||
case 'validate':
|
||
$slug = $argv[2] ?? null;
|
||
if (!$slug) { echo "Usage: validate SLUG\n"; exit(1); }
|
||
$target = "/var/www/html/products/{$slug}.html";
|
||
if (!file_exists($target)) { echo "NOT FOUND: $target\n"; exit(1); }
|
||
$c = file_get_contents($target);
|
||
$report = [
|
||
'exists' => true,
|
||
'size' => strlen($c),
|
||
'has_doctype' => str_contains($c, '<!DOCTYPE html>'),
|
||
'has_title' => str_contains($c, '<title>'),
|
||
'has_og' => str_contains($c, 'og:title'),
|
||
'has_suite_link' => str_contains($c, '/solutions/'),
|
||
'forbidden_hits' => [],
|
||
];
|
||
foreach (FORBIDDEN_TERMS as $t) {
|
||
$pattern = '/\b' . preg_quote($t, '/') . '\b/';
|
||
if (preg_match($pattern, $c)) $report['forbidden_hits'][] = $t;
|
||
}
|
||
$report['doctrine_108_pass'] = empty($report['forbidden_hits']);
|
||
echo json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n";
|
||
break;
|
||
|
||
default:
|
||
echo "wevia-site-builder.php\n";
|
||
echo "Usage:\n";
|
||
echo " build SLUG — Build single product page\n";
|
||
echo " build_all — Build all 10 missing product pages\n";
|
||
echo " list — List available products\n";
|
||
echo " scan_forbidden — Scan site for doctrine 108 forbidden terms\n";
|
||
echo " validate SLUG — Validate an existing built page\n";
|
||
break;
|
||
}
|