Files
weval-l99/wevia-site-builder-v2-light-pre-em.php
opus-wire 7f67eb6bdf auto-push
2026-04-18 14:33:55 +02:00

510 lines
37 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// wevia-site-builder.php v2.0 — 2026-04-18 — Phase B1 doctrine 108 §9 (light default + toggle)
// Génère pages produit WEVAL en thème clair par défaut avec toggle jour/nuit
declare(strict_types=1);
const FORBIDDEN_TERMS = [
'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',
'SAP Gold', 'Gold Partner',
'Paperclip', 'DeerFlow', 'MiroFish', 'OSS Discovery', 'Cowork',
'131K+', '131000', '131 000', 'Tunisie · Maroc · Algérie',
'TN/MA/DZ', 'TN · MA · DZ',
];
const PRODUCTS = [
'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 &amp; 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 &amp; 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 &amp; 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', 'Multi-user'], ['IA intégrée', 'Contextuelle'], ['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, Visio ; export multi-format.'],
],
],
'stackscan' => [
'name' => 'StackScan', 'tagline' => 'Audit &amp; 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'], ['Priorisation', 'Impact × effort']],
'features' => [
['SBOM automatique', 'Génération Software Bill of Materials au format CycloneDX ou SPDX, exports continus.'],
['Licences &amp; 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 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.'],
],
],
'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 &amp; 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.'],
],
],
];
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'],
],
];
// Light + Dark accent palettes (per suite)
const ACCENTS = [
'teal' => ['light' => '#0d9488', 'dark' => '#00c9a7', 'soft_l' => 'rgba(13,148,136,.08)', 'soft_d' => 'rgba(0,201,167,.12)'],
'purple' => ['light' => '#6f5cff', 'dark' => '#7c5cfc', 'soft_l' => 'rgba(111,92,255,.08)', 'soft_d' => 'rgba(124,92,252,.12)'],
'gold' => ['light' => '#b88a2e', 'dark' => '#f0c674', 'soft_l' => 'rgba(184,138,46,.08)', 'soft_d' => 'rgba(240,198,116,.12)'],
'coral' => ['light' => '#dc3e3e', 'dark' => '#ff6b6b', 'soft_l' => 'rgba(220,62,62,.08)', 'soft_d' => 'rgba(255,107,107,.12)'],
];
function get_template(): string {
return <<<'HTML'
<!DOCTYPE html>
<html lang="fr" data-theme="light"><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=Inter:wght@300;400;500;600;700;800&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet">
<script>(function(){var t=localStorage.getItem('weval-theme')||'light';document.documentElement.setAttribute('data-theme',t);})();</script>
<style>
:root{--bg:#ffffff;--bg-alt:#fafbfc;--surface:#ffffff;--text:#1a1f3a;--text-soft:#5a6480;--text-dim:#8893a8;--border:rgba(26,31,58,.08);--border-mid:rgba(26,31,58,.14);--shadow:0 1px 3px rgba(26,31,58,.04),0 8px 24px rgba(26,31,58,.04);--shadow-hover:0 2px 6px rgba(26,31,58,.06),0 16px 40px rgba(26,31,58,.08);--a:{{A_LIGHT}};--a-soft:{{A_SOFT_L}};--btn-p:#5b4cdb;--btn-p-h:#4a3dc4}
html[data-theme="dark"]{--bg:#05080f;--bg-alt:#080c18;--surface:#0c1222;--text:#edf2f7;--text-soft:#a8b4c8;--text-dim:#7a8ba5;--border:rgba(255,255,255,.06);--border-mid:rgba(255,255,255,.12);--shadow:0 1px 3px rgba(0,0,0,.3),0 8px 24px rgba(0,0,0,.3);--shadow-hover:0 2px 6px rgba(0,0,0,.4),0 16px 40px rgba(0,0,0,.4);--a:{{A_DARK}};--a-soft:{{A_SOFT_D}};--btn-p:#7c5cfc;--btn-p-h:#9277ff}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{font-family:'Inter',sans-serif;background:var(--bg);color:var(--text);-webkit-font-smoothing:antialiased;transition:background .3s,color .3s}
body::before{content:'';position:fixed;inset:0;background-image:radial-gradient(circle at 20% 10%,var(--a-soft) 0%,transparent 40%),radial-gradient(circle at 80% 60%,var(--a-soft) 0%,transparent 45%);pointer-events:none;opacity:.6;z-index:-1;transition:opacity .3s}
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(20px);background:color-mix(in srgb,var(--bg) 85%,transparent);border-bottom:1px solid var(--border)}
.logo{font-weight:800;font-size:1.35rem;letter-spacing:-.035em;display:flex;align-items:center;gap:.5rem;color:var(--text);text-decoration:none}
.logo-dot{width:10px;height:10px;border-radius:50%;background:var(--a);box-shadow:0 0 18px var(--a-soft)}
.nav-r{display:flex;gap:1.6rem;align-items:center}
.nav-r a{color:var(--text-soft);text-decoration:none;font-size:.86rem;font-weight:500;transition:color .25s}
.nav-r a:hover{color:var(--a)}
.btn-n{background:var(--btn-p);color:#fff;padding:.6rem 1.3rem;border-radius:8px;font-weight:600;font-size:.84rem;text-decoration:none;transition:all .2s;border:none;cursor:pointer}
.btn-n:hover{background:var(--btn-p-h);transform:translateY(-1px)}
.theme-toggle{width:38px;height:38px;border-radius:50%;background:var(--bg-alt);border:1px solid var(--border);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;color:var(--text-soft)}
.theme-toggle:hover{border-color:var(--a);color:var(--a);transform:translateY(-1px)}
.theme-toggle svg{width:18px;height:18px}
html[data-theme="light"] .icon-moon{display:none}
html[data-theme="dark"] .icon-sun{display:none}
.hero{min-height:92vh;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:9rem 4% 5rem;position:relative;overflow:hidden}
.badge{display:inline-flex;align-items:center;gap:.5rem;background:var(--a-soft);border:1px solid var(--a-soft);border-radius:100px;padding:.42rem 1.05rem;font-size:.72rem;font-weight:700;color:var(--a);margin-bottom:2rem;font-family:'Space Mono',monospace;letter-spacing:.05em}
.badge::before{content:'';width:6px;height:6px;background:var(--a);border-radius:50%;animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}
h1{font-size:clamp(2.4rem,5vw,4.1rem);font-weight:800;line-height:1.04;letter-spacing:-.04em;max-width:900px;margin-bottom:1.5rem;color:var(--text)}
h1 em{font-style:normal;color:var(--a)}
.sub{font-size:clamp(1rem,1.2vw,1.1rem);color:var(--text-soft);max-width:700px;line-height:1.65;margin-bottom:2.5rem;font-weight:400}
.btns{display:flex;gap:1rem;flex-wrap:wrap;justify-content:center}
.btn-p{background:var(--btn-p);color:#fff;padding:.95rem 2rem;border-radius:10px;font-weight:600;font-size:.9rem;text-decoration:none;transition:all .25s;display:inline-flex;align-items:center;gap:.4rem;box-shadow:0 4px 12px color-mix(in srgb,var(--btn-p) 25%,transparent)}
.btn-p:hover{background:var(--btn-p-h);transform:translateY(-2px);box-shadow:0 8px 24px color-mix(in srgb,var(--btn-p) 30%,transparent)}
.btn-o{background:transparent;color:var(--text);padding:.95rem 2rem;border-radius:10px;font-weight:500;font-size:.9rem;text-decoration:none;border:1px solid var(--border-mid);transition:all .25s;display:inline-flex;align-items:center;gap:.4rem}
.btn-o:hover{border-color:var(--a);color:var(--a);background:var(--a-soft)}
.suite-chip{display:inline-flex;align-items:center;gap:.5rem;margin-top:1.5rem;padding:.38rem .95rem;background:var(--bg-alt);border:1px solid var(--border);border-radius:100px;font-size:.74rem;color:var(--text-soft);font-family:'Space Mono',monospace;font-weight:600;letter-spacing:.04em;text-decoration:none;transition:all .2s}
.suite-chip:hover{color:var(--a);border-color:var(--a)}
.sec{padding:5.5rem 4%;max-width:1180px;margin:0 auto}
.sec.alt{background:var(--bg-alt);max-width:none;padding-left:max(4%,calc((100% - 1180px) / 2));padding-right:max(4%,calc((100% - 1180px) / 2))}
.stag{font-family:'Space Mono',monospace;font-size:.72rem;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:.9rem;max-width:700px;color:var(--text)}
h2 em{font-style:normal;color:var(--a)}
.sd{color:var(--text-soft);font-size:1rem;line-height:1.65;max-width:600px;margin-bottom:3rem;font-weight:400}
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:0;background:var(--surface);border:1px solid var(--border);border-radius:14px;overflow:hidden;margin:2rem 0 3rem;box-shadow:var(--shadow)}
.stat{padding:1.6rem 1rem;text-align:center;border-right:1px solid var(--border)}
.stat:last-child{border-right:none}
.stat-n{font-family:'Space Mono',monospace;font-size:1.35rem;font-weight:700;color:var(--a);line-height:1}
.stat-l{font-size:.72rem;color:var(--text-soft);margin-top:.5rem;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(--surface);border:1px solid var(--border);border-radius:14px;padding:1.7rem;transition:all .3s;position:relative;overflow:hidden;box-shadow:var(--shadow)}
.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);box-shadow:var(--shadow-hover)}
.fcd:hover::before{opacity:1}
.fcd h3{font-size:1.02rem;font-weight:700;margin-bottom:.55rem;letter-spacing:-.01em;color:var(--text)}
.fcd p{font-size:.87rem;color:var(--text-soft);line-height:1.6}
.suite-box{background:var(--surface);border:1px solid var(--border);border-radius:18px;padding:2.2rem;display:grid;grid-template-columns:1.2fr .8fr;gap:2.2rem;align-items:center;margin-top:2rem;box-shadow:var(--shadow)}
.suite-box-l h3{font-size:1.35rem;font-weight:700;margin-bottom:.7rem;letter-spacing:-.02em;color:var(--text)}
.suite-box-l p{color:var(--text-soft);font-size:.94rem;line-height:1.6;margin-bottom:1.2rem}
.suite-box-r{display:flex;flex-wrap:wrap;gap:.4rem}
.apptag{background:var(--bg-alt);border:1px solid var(--border);border-radius:6px;padding:.32rem .7rem;font-size:.72rem;color:var(--text);font-family:'Space Mono',monospace;font-weight:500}
.apptag.self{background:var(--a-soft);color:var(--a);border-color:var(--a)}
.cta{text-align:center;padding:4.5rem 2rem;margin:3rem 4% 2rem;background:var(--bg-alt);border:1px solid var(--border);border-radius:22px;position:relative;overflow:hidden;max-width:1100px;margin-left:auto;margin-right:auto}
.cta h2{margin:0 auto .9rem}
.cta p{color:var(--text-soft);max-width:560px;margin:0 auto 2rem}
footer{padding:2.5rem 4% 1.5rem;max-width:1180px;margin:2rem auto 0;border-top:1px solid var(--border)}
.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:.85rem}
.foot-links a{color:var(--text-soft);text-decoration:none;transition:color .2s}
.foot-links a:hover{color:var(--a)}
.foot-b{font-size:.74rem;color:var(--text-dim);font-family:'Space Mono',monospace;letter-spacing:.04em}
@media(max-width:900px){h1{font-size:2.2rem}.stats{grid-template-columns:1fr 1fr}.stat:nth-child(odd){border-right:1px solid var(--border)}.stat:nth-child(even){border-right:none}.stat{border-bottom:1px solid var(--border)}.g3{grid-template-columns:1fr}.suite-box{grid-template-columns:1fr;padding:1.6rem}.nav-r a:not(.btn-n):not(.theme-toggle){display:none}}
@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>
<a class="logo" href="/"><span class="logo-dot"></span>{{NAME}}<span style="color:var(--a)">.</span></a>
<div class="nav-r">
<a href="/">Accueil</a>
<a href="/products/">Produits</a>
<a href="/marketplace">Marketplace</a>
<button class="theme-toggle" onclick="(function(){var c=document.documentElement.getAttribute('data-theme')==='dark'?'light':'dark';document.documentElement.setAttribute('data-theme',c);localStorage.setItem('weval-theme',c);})()" aria-label="Basculer thème jour/nuit">
<svg class="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/></svg>
<svg class="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
</button>
<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 alt">
<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:.82rem">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">
<a class="logo" href="/"><span class="logo-dot"></span>WEVAL<span style="color:var(--a)">.</span></a>
<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 &amp; éditeur IA souveraine · Partenaire Écosystème SAP · Huawei Cloud Certified</div>
</footer>
</body></html>
HTML;
}
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']];
$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));
}
$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));
}
$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));
}
$desc_short = mb_substr(strip_tags($p['desc']), 0, 140);
$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,
'{{A_LIGHT}}' => $accent['light'], '{{A_DARK}}' => $accent['dark'],
'{{A_SOFT_L}}' => $accent['soft_l'], '{{A_SOFT_D}}' => $accent['soft_d'],
];
$html = strtr($html, $vars);
foreach (FORBIDDEN_TERMS as $term) {
$pattern = '/\b' . preg_quote($term, '/') . '\b/';
if (preg_match($pattern, $html)) {
return ['ok' => false, 'slug' => $slug, 'error' => "Forbidden term: $term"];
}
}
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'];
$target = "/var/www/html/products/{$slug}.html";
if (file_exists($target)) {
$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']), 'theme' => 'light+toggle'];
}
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;
}
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); }
echo json_encode(build_page($slug), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . "\n";
break;
case 'build_all':
$ok = 0; $fail = 0;
foreach (array_keys(PRODUCTS) as $slug) {
$r = build_page($slug);
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, theme=' . $r['theme']) : $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/'),
'has_theme_toggle' => str_contains($c, 'weval-theme'),
'light_by_default' => str_contains($c, 'data-theme="light"'),
'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 v2 (light default + toggle)\n";
echo " build SLUG | build_all | list | scan_forbidden | validate SLUG\n";
}