Files
html/products/academy-elearning.html
Opus 6e240b4f31 phase65 doctrine 203 WEVIA GEMINI UX APPLY 10 PAGES PREMIUM CSS + handler v2 sudo-chattr
10 products pages with Gemini premium CSS applied (marker DOCTRINE-201 verified):
- leadforge (52279B) academy (38428) consulting (30061) ai-sdr (29446)
- arsenal (47227) auditai (37500) academy-elearning (20999)
- ecosysteme-ia-maroc (21032) roi-calculator (24168) linkedin-manager (25793)
All HTTP 200 confirmed, Playwright audit tr:0 br:0 ZERO overlap regression

Handler v2 improvements (doctrine 203):
- wgux-apply.py: sudo chattr -i/+i (fix silent failure batch mode)
- Verify post-apply: marker presence + size delta > 0
- Restore from GOLD backup if corruption detected
- fallback sudo tee if direct write PermissionError

Scripts deployed:
- /var/www/html/api/wevia-gemini-ux-apply.sh (orchestrator)
- /var/www/html/api/wgux-build-payload.py (Gemini prompt builder, maxTokens 16000)
- /var/www/html/api/wgux-parse.py (robust JSON parser)
- /var/www/html/api/wgux-apply.py v2 (sudo chattr + verify)
- /var/www/html/api/wgux-shot.js (Playwright screenshot)

Intents LIVE:
- intent-opus4-wevia_gemini_ux_fix (review mode)
- intent-opus4-wevia_gemini_ux_apply (apply mode)
10 NL triggers each: gemini ux, refais ux, apply ux gemini, audit ux gemini, etc.

Gap batch reliability identified (phase 62-64):
- Direct call sudo wgux-apply.py WORKS
- Orchestrator via nohup sudo bash -c WORKS in foreground
- Background batch parallel: sporadic silent failure despite sudo chattr
- Root cause: sudo context loss in nested child process under FPM
- Recommendation next phase: appel seq direct sans orchestrator BG

Cumul session Opus:
- 62 tags (incluant phase 65)
- 42 doctrines (146-203)
- 428 pages UX doctrine 60
- 10 pages Gemini premium CSS APPLIED E2E
- NR 153/153 invariant 65 phases
2026-04-24 18:33:06 +02:00

789 lines
20 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WEVAL Academy E-Learning — Formations IA avec Certification</title>
<meta name="description" content="Formations IA complètes avec quiz et certification. 11 modules: Prompt Engineering, LLM Souverain, Cloud IA, Sécurité. Certifiez vos compétences IA.">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--primary: #e94560;
--dark: #0f172a;
--bg: #1e293b;
--text: #f1f5f9;
--gray: #64748b;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: var(--dark);
color: var(--text);
line-height: 1.6;
}
.header {
background: var(--bg);
padding: 1.5rem 2rem;
border-bottom: 1px solid rgba(255,255,255,0.1);
position: sticky;
top: 0;
z-index: 100;
}
.header-content {
max-width: 1400px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: space-between;
}
.logo {
font-size: 1.5rem;
font-weight: 800;
color: white;
text-decoration: none;
display: flex;
align-items: center;
gap: 0.5rem;
}
.logo span {
color: var(--primary);
}
.nav-links {
display: flex;
gap: 2rem;
align-items: center;
}
.nav-links a {
color: var(--text);
text-decoration: none;
font-weight: 500;
transition: color 0.3s;
}
.nav-links a:hover {
color: var(--primary);
}
.hero {
max-width: 1400px;
margin: 0 auto;
padding: 4rem 2rem;
text-align: center;
}
.hero h1 {
font-size: 3rem;
font-weight: 800;
margin-bottom: 1rem;
background: linear-gradient(135deg, var(--primary), #ff6b95);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero p {
font-size: 1.25rem;
color: var(--gray);
max-width: 700px;
margin: 0 auto 2rem;
}
.stats {
display: flex;
gap: 3rem;
justify-content: center;
margin-top: 3rem;
}
.stat {
text-align: center;
}
.stat-value {
font-size: 2.5rem;
font-weight: 800;
color: var(--primary);
}
.stat-label {
color: var(--gray);
font-size: 0.9rem;
}
#root {
max-width: 1400px;
margin: 2rem auto;
padding: 0 2rem;
}
.loading {
text-align: center;
padding: 4rem 2rem;
color: var(--gray);
}
.loading::after {
content: '⏳';
display: block;
font-size: 3rem;
margin-top: 1rem;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
@media (max-width: 768px) {
.hero h1 {
font-size: 2rem;
}
.stats {
flex-direction: column;
gap: 1.5rem;
}
.nav-links {
display: none;
}
}
</style>
<!-- DOCTRINE-60-UX-ENRICH products-batch-doctrine195 -->
<style id="wtp-doctrine60-ux-premium">
:root {
--wtp-bg-start:#0a0f1c; --wtp-bg-end:#0f172a;
--wtp-surface:rgba(15,23,42,.85); --wtp-surface-hover:rgba(30,41,59,.9);
--wtp-border:rgba(99,102,241,.25); --wtp-border-hover:rgba(99,102,241,.5);
--wtp-text:#e2e8f0; --wtp-text-dim:#94a3b8; --wtp-text-bright:#f1f5f9;
--wtp-primary:#6366f1; --wtp-primary-hover:#7c7feb;
--wtp-accent:#8b5cf6; --wtp-success:#10b981; --wtp-warning:#f59e0b; --wtp-danger:#ef4444;
--wtp-radius:12px; --wtp-shadow:0 4px 24px rgba(99,102,241,.15); --wtp-shadow-lg:0 8px 48px rgba(99,102,241,.25);
--wtp-transition:all .2s cubic-bezier(.4,0,.2,1);
--wtp-font:'Inter',-apple-system,BlinkMacSystemFont,sans-serif;
--wtp-font-mono:'JetBrains Mono',monospace;
}
.wtp-card{background:var(--wtp-surface);border:1px solid var(--wtp-border);border-radius:var(--wtp-radius);padding:20px;transition:var(--wtp-transition)}
.wtp-card:hover{border-color:var(--wtp-border-hover);box-shadow:var(--wtp-shadow)}
.wtp-btn{background:linear-gradient(135deg,var(--wtp-primary),var(--wtp-accent));color:#fff;padding:10px 20px;border:none;border-radius:8px;cursor:pointer;font-weight:600;transition:var(--wtp-transition)}
.wtp-btn:hover{transform:translateY(-1px);box-shadow:var(--wtp-shadow)}
.wtp-badge{display:inline-flex;align-items:center;padding:4px 10px;background:var(--wtp-surface);border:1px solid var(--wtp-border);border-radius:20px;font-size:12px;color:var(--wtp-text-dim)}
@media (max-width:768px){#weval-bot-widget{bottom:100px !important;right:16px !important;z-index:10001 !important}#weval-bot-btn{width:48px !important;height:48px !important}#weval-bot-btn svg{width:22px !important;height:22px !important}#footer_banner,.footer-banner,[class*="footer-bandeau"]{z-index:9990 !important}}
</style>
<!-- DOCTRINE-201-GEMINI-APPLY-20260424-173928 -->
<style>
/* Premium WEVAL CSS */
:root {
--wtp-bg: #161625; /* Darker, richer background */
--wtp-card: #212135; /* Dark card background */
--wtp-primary: #ff4081; /* WEVAL pink/magenta */
--wtp-accent: #d81b60; /* Deeper accent pink */
--wtp-text-light: #e0e0e0;
--wtp-text-muted: #a0a0b0;
--wtp-border: rgba(255, 255, 255, 0.08);
--wtp-shadow-light: rgba(0, 0, 0, 0.2);
--wtp-shadow-strong: rgba(0, 0, 0, 0.4);
}
/* Global Body & Typography */
body {
font-family: 'Inter', sans-serif; /* Modern sans-serif font */
background-color: var(--wtp-bg);
color: var(--wtp-text-light);
margin: 0;
padding: 0;
line-height: 1.6;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, h5, h6 {
color: var(--wtp-text-light);
margin-top: 1.5em;
margin-bottom: 0.8em;
font-weight: 700;
}
h1 { font-size: 2.8em; }
h2 { font-size: 2.2em; }
h3 { font-size: 1.8em; }
p {
font-size: 1.1em;
color: var(--wtp-text-muted);
}
a {
color: var(--wtp-primary);
text-decoration: none;
transition: color 0.3s ease;
}
a:hover {
color: var(--wtp-accent);
}
/* Layout & Structure */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* Header & Navigation */
header {
background-color: var(--wtp-bg);
padding: 15px 0;
border-bottom: 1px solid var(--wtp-border);
display: flex;
justify-content: space-between;
align-items: center;
position: sticky;
top: 0;
z-index: 1000;
box-shadow: 0 2px 10px var(--wtp-shadow-light);
}
.weval-logo {
font-size: 1.8em;
font-weight: 800;
color: var(--wtp-text-light);
display: flex;
align-items: center;
}
.weval-logo span {
color: var(--wtp-primary);
margin-left: 5px;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
}
nav ul li {
margin-left: 30px;
}
nav ul li a {
color: var(--wtp-text-muted);
font-weight: 500;
font-size: 1.05em;
position: relative;
}
nav ul li a::after {
content: '';
position: absolute;
left: 0;
bottom: -5px;
width: 0;
height: 2px;
background-color: var(--wtp-primary);
transition: width 0.3s ease;
}
nav ul li a:hover::after {
width: 100%;
}
nav ul li a.active {
color: var(--wtp-primary);
}
nav ul li a.active::after {
width: 100%;
}
/* .wtp-hero-premium */
.wtp-hero-premium {
text-align: center;
padding: 80px 20px 60px;
background: linear-gradient(135deg, var(--wtp-bg) 0%, #2a1a3a 100%); /* Deep purple-ish gradient */
position: relative;
overflow: hidden;
border-bottom: 1px solid var(--wtp-border);
}
.wtp-hero-premium::before { /* Backdrop effect */
content: '';
position: absolute;
top: -50px;
left: -50px;
right: -50px;
bottom: -50px;
background: radial-gradient(circle at 50% 0%, rgba(255, 64, 129, 0.1) 0%, transparent 70%);
filter: blur(80px);
z-index: 0;
opacity: 0.6;
}
.wtp-hero-premium > * {
position: relative;
z-index: 1;
}
.wtp-hero-premium h1 {
font-size: 3.5em;
color: var(--wtp-primary);
margin-bottom: 0.3em;
text-shadow: 0 0 15px rgba(255, 64, 129, 0.4);
}
.wtp-hero-premium h1 .icon {
margin-right: 15px;
color: var(--wtp-primary);
}
.wtp-hero-premium p {
max-width: 700px;
margin: 0.5em auto 2em;
font-size: 1.2em;
color: var(--wtp-text-muted);
}
/* KPI Section */
.kpi-section {
display: flex;
justify-content: center;
gap: 50px;
margin-top: 40px;
margin-bottom: 60px;
}
.kpi-item {
text-align: center;
}
.kpi-item .number {
font-size: 3.5em;
font-weight: 800;
color: var(--wtp-primary);
line-height: 1;
}
.kpi-item .label {
font-size: 1em;
color: var(--wtp-text-muted);
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 5px;
}
/* .wtp-kpi-card */
.wtp-kpi-card {
background-color: var(--wtp-card);
border-radius: 12px;
padding: 25px;
box-shadow: 0 8px 25px var(--wtp-shadow-strong);
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
border: 1px solid var(--wtp-border);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.wtp-kpi-card:hover {
transform: translateY(-5px);
box-shadow: 0 12px 35px var(--wtp-shadow-strong);
}
.wtp-kpi-card .card-title {
font-size: 1.4em;
font-weight: 600;
color: var(--wtp-text-light);
margin-bottom: 15px;
}
.wtp-kpi-card .card-value {
font-size: 2.5em;
font-weight: 800;
color: var(--wtp-primary);
margin-bottom: 10px;
}
.wtp-kpi-card .sparkline-svg { /* Placeholder for sparkline SVG */
width: 100%;
height: 60px;
margin-top: 15px;
background: rgba(255, 255, 255, 0.05);
border-radius: 5px;
}
.wtp-kpi-card .sparkline-svg svg {
width: 100%;
height: 100%;
}
/* Catalogue Section */
.catalogue-section {
background-color: var(--wtp-card);
border-radius: 12px;
padding: 40px;
margin-top: 60px;
box-shadow: 0 8px 25px var(--wtp-shadow-strong);
border: 1px solid var(--wtp-border);
}
.catalogue-section h2 {
font-size: 2.2em;
color: var(--wtp-text-light);
display: flex;
align-items: center;
margin-top: 0;
margin-bottom: 15px;
}
.catalogue-section h2 .icon {
margin-right: 15px;
color: var(--wtp-primary);
}
.catalogue-section p {
margin-bottom: 30px;
font-size: 1.05em;
}
.module-card {
background-color: #2a2a40; /* Slightly different dark background for module */
border-radius: 10px;
padding: 25px;
margin-bottom: 25px;
border-left: 5px solid var(--wtp-primary);
box-shadow: 0 4px 15px var(--wtp-shadow-light);
}
.module-card .status {
display: flex;
align-items: center;
font-weight: 600;
color: #4CAF50; /* Green for available */
margin-bottom: 15px;
}
.module-card .status .icon {
margin-right: 10px;
font-size: 1.2em;
}
.module-card p {
font-size: 1em;
margin-bottom: 20px;
color: var(--wtp-text-muted);
}
.module-card ul {
list-style: none;
padding: 0;
margin: 0;
}
.module-card ul li {
position: relative;
padding-left: 25px;
margin-bottom: 10px;
color: var(--wtp-text-light);
}
.module-card ul li::before {
content: '•'; /* Custom bullet point */
position: absolute;
left: 0;
color: var(--wtp-primary);
font-size: 1.2em;
line-height: 1;
}
/* .wtp-status-led */
@keyframes pulse {
0% {
transform: scale(0.8);
box-shadow: 0 0 0 0 rgba(255, 64, 129, 0.7);
}
70% {
transform: scale(1);
box-shadow: 0 0 0 15px rgba(255, 64, 129, 0);
}
100% {
transform: scale(0.8);
box-shadow: 0 0 0 0 rgba(255, 64, 129, 0);
}
}
.wtp-status-led {
display: inline-block;
width: 12px;
height: 12px;
background-color: var(--wtp-primary);
border-radius: 50%;
animation: pulse 2s infinite;
margin-left: 10px; /* Example usage */
}
/* .wtp-action-btn */
.wtp-action-btn {
display: inline-block;
padding: 14px 30px;
border-radius: 8px;
font-size: 1.1em;
font-weight: 600;
color: var(--wtp-text-light);
background-image: linear-gradient(45deg, var(--wtp-primary) 0%, var(--wtp-accent) 100%);
border: none;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 5px 15px rgba(255, 64, 129, 0.4);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.wtp-action-btn:hover {
background-image: linear-gradient(45deg, var(--wtp-accent) 0%, var(--wtp-primary) 100%); /* Shift gradient */
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(255, 64, 129, 0.6);
}
.wtp-action-btn:active {
transform: translateY(0);
box-shadow: 0 3px 10px rgba(255, 64, 129, 0.3);
}
/* Media Query for Mobile */
@media (max-width: 768px) {
.container {
padding: 0 15px;
}
header {
flex-direction: column;
align-items: flex-start;
padding-bottom: 10px;
}
nav ul {
margin-top: 15px;
flex-wrap: wrap;
justify-content: center;
}
nav ul li {
margin: 0 10px 10px 0;
}
.wtp-hero-premium {
padding: 60px 15px 40px;
}
.wtp-hero-premium h1 {
font-size: 2.5em;
}
.wtp-hero-premium p {
font-size: 1em;
}
.kpi-section {
flex-direction: column;
gap: 30px;
margin-top: 30px;
margin-bottom: 40px;
}
.kpi-item .number {
font-size: 2.8em;
}
.catalogue-section {
padding: 30px 20px;
margin-top: 40px;
}
.catalogue-section h2 {
font-size: 1.8em;
flex-direction: column;
align-items: flex-start;
}
.catalogue-section h2 .icon {
margin-bottom: 10px;
}
.module-card {
padding: 20px;
}
/* Anti-overlap for bot-widget */
.bot-widget { /* Assuming a class for a fixed bot widget */
bottom: 100px !important; /* Important to override other styles */
left: 15px;
right: 15px;
width: auto;
}
}
/* General elements from the image that need styling */
/* Assuming the main title is an h1 in .wtp-hero-premium */
/* Assuming the numbers are within .kpi-section .kpi-item */
/* Assuming the catalogue is .catalogue-section */
/* Assuming the module is .module-card */
/* Icons (if using font-awesome or similar) */
.fa-graduation-cap, .fa-book, .fa-check-circle {
/* Basic styling for icons */
font-family: 'Font Awesome 5 Free'; /* Example, adjust as needed */
font-weight: 900;
}
</style>
<!-- END-DOCTRINE-201 -->
</head>
<body>
<header class="header">
<div class="header-content">
<a href="/" class="logo">
WEVAL<span>Academy</span>
</a>
<nav class="nav-links">
<a href="/">Accueil</a>
<a href="/products/academy.html">Présentation</a>
<a href="/products/academy-elearning.html">Formations</a>
<a href="/wevia">Chat IA</a>
<a href="/booking.html">Contact</a>
</nav>
</div>
</header>
<section class="hero">
<h1>🎓 Formations IA avec Certification</h1>
<p>
11 modules complets avec quiz interactifs et certification officielle WEVAL.
Maîtrisez l'IA générative, le prompt engineering et les LLMs souverains.
</p>
<div class="stats">
<div class="stat">
<div class="stat-value">11</div>
<div class="stat-label">Formations</div>
</div>
<div class="stat">
<div class="stat-value">12</div>
<div class="stat-label">Quiz</div>
</div>
<div class="stat">
<div class="stat-value">45min</div>
<div class="stat-label">Durée moyenne</div>
</div>
</div>
</section>
<div id="root">
<div class="loading">
Chargement du module e-learning...
</div>
</div>
<script type="module">
// Import React depuis CDN
import React from 'https://esm.sh/react@18.2.0';
import ReactDOM from 'https://esm.sh/react-dom@18.2.0/client';
// Charger le module Academy
const loadAcademyModule = async () => {
try {
// Récupérer le code du module
const response = await fetch('/products/WevalIA-Academy-Module.jsx');
const moduleCode = await response.text();
// Créer un composant temporaire qui affiche les formations
const AcademyComponent = () => {
return React.createElement('div', {
style: {
background: '#1e293b',
borderRadius: '12px',
padding: '2rem',
marginBottom: '2rem'
}
}, [
React.createElement('h2', {
key: 'title',
style: {
fontSize: '1.8rem',
marginBottom: '1rem',
color: '#f1f5f9'
}
}, '📚 Catalogue des Formations'),
React.createElement('p', {
key: 'desc',
style: {
color: '#64748b',
marginBottom: '2rem'
}
}, 'Module e-learning complet extrait. 2013 lignes de code React avec 12 quiz intégrés.'),
React.createElement('div', {
key: 'info',
style: {
background: 'rgba(233, 69, 96, 0.1)',
border: '1px solid rgba(233, 69, 96, 0.3)',
borderRadius: '8px',
padding: '1.5rem',
marginTop: '1rem'
}
}, [
React.createElement('h3', {
key: 'info-title',
style: { color: '#e94560', marginBottom: '0.5rem' }
}, '✅ Module Disponible'),
React.createElement('p', {
key: 'info-text',
style: { color: '#f1f5f9', fontSize: '0.9rem' }
}, 'Le module e-learning complet (198KB, 2013 lignes) a été extrait du Git et est prêt pour intégration React. Il contient 11 formations complètes avec quiz interactifs et système de certification.'),
React.createElement('ul', {
key: 'formations',
style: {
marginTop: '1rem',
paddingLeft: '1.5rem',
color: '#cbd5e1'
}
}, [
'Introduction à l\'IA Générative',
'Prompt Engineering Fondamentaux',
'Prompt Engineering Avancé',
'LLM Souverain Ollama',
'Architecture Cloud IA',
'Sécurité IA',
'IA pour Managers',
'Automatisation IA',
'Comprendre LLM',
'IA Data Analytics',
'Guide Certifications IA'
].map((f, i) => React.createElement('li', {
key: i,
style: { marginBottom: '0.5rem' }
}, f))),
React.createElement('div', {
key: 'cta',
style: {
marginTop: '1.5rem',
padding: '1rem',
background: 'rgba(233, 69, 96, 0.2)',
borderRadius: '6px',
textAlign: 'center'
}
}, [
React.createElement('p', {
key: 'cta-text',
style: { color: '#f1f5f9', fontWeight: 600 }
}, '🚀 Module React complet prêt pour compilation'),
React.createElement('p', {
key: 'cta-details',
style: { color: '#94a3b8', fontSize: '0.85rem', marginTop: '0.5rem' }
}, 'Fichier: /var/www/html/products/WevalIA-Academy-Module.jsx (198KB)')
])
])
]);
};
// Render
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(React.createElement(AcademyComponent));
} catch (error) {
console.error('Erreur chargement module:', error);
document.getElementById('root').innerHTML = `
<div style="background: #dc2626; color: white; padding: 2rem; border-radius: 12px; text-align: center;">
<h3>❌ Erreur de chargement</h3>
<p style="margin-top: 1rem; opacity: 0.9;">${error.message}</p>
</div>
`;
}
};
// Charger au démarrage
loadAcademyModule();
</script>
</body>
</html>