Compare commits
34 Commits
0d4bc8121d
...
exos-rewor
| Author | SHA1 | Date | |
|---|---|---|---|
| f611bdcd7e | |||
| f7c846c85c | |||
| a74df51201 | |||
| 42650ca351 | |||
| 21a7359057 | |||
| 6bb7985512 | |||
| 090cbc19a2 | |||
| 794ae69fa0 | |||
| 88b075fb88 | |||
| b5f2eac842 | |||
| a42957ad41 | |||
| 421ae4c2bf | |||
| affa042c05 | |||
| 30817c829b | |||
| 41d8b98f96 | |||
| d251782842 | |||
| 66ed3c505f | |||
| 543bb6cd52 | |||
| a2a4fea004 | |||
| d351ee6efb | |||
| 0b4c2244fe | |||
| f720beaf3c | |||
| 2a2ed26563 | |||
| fb5c7e9720 | |||
| a418558393 | |||
| c1bd61c10c | |||
| 44be41b2b2 | |||
| 9140d2f468 | |||
| 75c5a1ac84 | |||
| 1e757ccda8 | |||
| f7f73591c1 | |||
| cf69373417 | |||
| 2227aa89d5 | |||
| 954c7d2b1a |
11
.claude/launch.json
Normal file
11
.claude/launch.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "0.0.1",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "static-site",
|
||||
"runtimeExecutable": "python3",
|
||||
"runtimeArgs": ["-m", "http.server", "8123"],
|
||||
"port": 8123
|
||||
}
|
||||
]
|
||||
}
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,2 +1,5 @@
|
||||
|
||||
.DS_Store
|
||||
|
||||
# Contient le mot de passe SQL Server — à éditer uniquement sur bsite.net
|
||||
exercices/memory-pictogrammes/api/web.config
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Index Documentation Technique & Biologie | NextGN Formation</title>
|
||||
<title>Index Documentation Technique & Biologie | Gauthier Chombart & Nathan Chauwin</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=DM+Sans:ital,wght@0,300;0,400;0,500;1,300&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
@@ -506,7 +506,7 @@
|
||||
|
||||
<nav class="nav-header">
|
||||
<a href="index.html" class="header-logo">
|
||||
<span>NextGN</span> Formation
|
||||
Gauthier Chombart & Nathan Chauwin
|
||||
</a>
|
||||
<div class="header-nav">
|
||||
<a href="index.html#formations">Exercices interactifs</a>
|
||||
@@ -548,7 +548,7 @@
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2026 NextGN Formation - Index Documentation Technique & Biologie</p>
|
||||
<p>© 2026 Gauthier Chombart & Nathan Chauwin<br>Tous droits réservés — Formations Certibiocide & Techniques — Formateurs indépendants</p>
|
||||
<p>Tous droits réservés — Gauthier Chombart & Nathan Chauwin — Formateurs indépendants</p>
|
||||
</footer>
|
||||
|
||||
|
||||
BIN
data/ghs05-corrosif.jpg
Normal file
BIN
data/ghs05-corrosif.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
BIN
data/ghs07-nocif.jpg
Normal file
BIN
data/ghs07-nocif.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
BIN
data/ghs09-environnement.jpg
Normal file
BIN
data/ghs09-environnement.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,7 @@
|
||||
justify-content: center;
|
||||
padding: 2rem;
|
||||
padding-top: calc(70px + 2rem);
|
||||
padding-bottom: calc(52px + 2rem);
|
||||
padding-bottom: calc(84px + 2rem);
|
||||
opacity: 0;
|
||||
transition: opacity 0.4s ease;
|
||||
overflow-y: auto;
|
||||
@@ -38,73 +38,67 @@
|
||||
transition: width 0.4s ease;
|
||||
}
|
||||
|
||||
/* PHASE INDICATOR */
|
||||
.phase-badge {
|
||||
position: fixed;
|
||||
top: 80px; right: 16px;
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
padding: 4px 12px;
|
||||
border-radius: 20px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
/* BOTTOM BAR */
|
||||
.bottom-bar {
|
||||
position: fixed;
|
||||
bottom: 0; left: 0; right: 0;
|
||||
height: 52px;
|
||||
height: 84px;
|
||||
background: rgba(250, 238, 218, 0.98);
|
||||
border-top: 2px solid var(--amber);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
justify-content: center;
|
||||
padding: 0 20px;
|
||||
z-index: 100;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
/* SLIDE NAV */
|
||||
.bottom-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
.footer-btn {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
padding: 11px 24px;
|
||||
border-radius: 40px;
|
||||
border: 1.5px solid var(--amber);
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
line-height: 1;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.footer-btn:hover { transform: translateY(-1px); }
|
||||
.footer-btn:active { transform: scale(0.98); }
|
||||
.footer-btn.is-primary { background: var(--amber); color: #fff; }
|
||||
.footer-btn.is-primary:hover { background: var(--amber-dark); }
|
||||
.footer-btn.is-secondary { background: transparent; color: var(--amber-dark); }
|
||||
.footer-btn.is-secondary:hover { background: rgba(186,117,23,0.08); }
|
||||
.slide-counter {
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
font-size: 12px;
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-weight: 600;
|
||||
color: var(--amber-dark);
|
||||
}
|
||||
|
||||
/* BACK BUTTON */
|
||||
.back-btn {
|
||||
background: none;
|
||||
border: 0.5px solid var(--amber);
|
||||
border-radius: 20px;
|
||||
padding: 6px 16px;
|
||||
font-size: 12px;
|
||||
color: var(--amber-dark);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
@media (max-width: 560px) {
|
||||
.slide-counter { display: none; }
|
||||
}
|
||||
.back-btn:hover { background: rgba(186,117,23,0.08); }
|
||||
|
||||
/* FORMATEUR SELECTOR */
|
||||
.formateur-btn {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
padding: 10px 24px;
|
||||
border-radius: 30px;
|
||||
border: 1.5px solid var(--border);
|
||||
background: white;
|
||||
color: var(--text-muted);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
flex: 1;
|
||||
flex: 1; font-family: 'DM Sans', sans-serif; font-size: 13.5px;
|
||||
padding: 9px 13px; border: 1px solid var(--border); border-radius: 10px;
|
||||
background: var(--bg); color: var(--text); cursor: pointer; transition: all 0.2s ease;
|
||||
}
|
||||
.formateur-btn:hover { border-color: var(--amber); color: var(--amber); }
|
||||
.formateur-btn.selected { background: var(--amber-light); border-color: var(--amber); color: var(--amber-dark); font-weight: 700; }
|
||||
.formateur-btn:hover { border-color: var(--amber); }
|
||||
.formateur-btn.selected { background: var(--amber); border-color: var(--amber); color: #fff; }
|
||||
|
||||
/* CARDS & BUTTONS */
|
||||
.btn {
|
||||
@@ -246,40 +240,42 @@
|
||||
.q-item { flex-direction: column; align-items: stretch; }
|
||||
.q-item .q-head { display: flex; align-items: flex-start; gap: 12px; }
|
||||
|
||||
/* IDENTIFICATION SCREEN */
|
||||
.id-form {
|
||||
/* IDENTIFICATION SCREEN — carte modèle BioCID / FDS */
|
||||
.identity-card {
|
||||
background: white;
|
||||
border: 0.5px solid var(--border);
|
||||
border-radius: 14px;
|
||||
padding: 16px 18px;
|
||||
max-width: 460px;
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
margin: 1.25rem 0;
|
||||
margin: 1.25rem auto;
|
||||
text-align: left;
|
||||
}
|
||||
.id-field label {
|
||||
display: block;
|
||||
.identity-card .identity-title {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 11px;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 6px;
|
||||
text-align: left;
|
||||
color: var(--amber-dark);
|
||||
margin-bottom: 10px;
|
||||
display: flex; align-items: center; gap: 6px;
|
||||
}
|
||||
.id-field input {
|
||||
width: 100%;
|
||||
.identity-fields { display: flex; flex-direction: column; gap: 8px; }
|
||||
.identity-fields input {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-size: 15px;
|
||||
padding: 12px 16px;
|
||||
border: 1.5px solid var(--border);
|
||||
border-radius: 10px;
|
||||
background: white;
|
||||
font-size: 13.5px;
|
||||
color: var(--text);
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
padding: 9px 13px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.id-field input:focus {
|
||||
outline: none;
|
||||
border-color: var(--amber);
|
||||
}
|
||||
.identity-fields input:focus { outline: none; border-color: var(--amber); background: white; }
|
||||
.formateur-label { font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-muted); margin: 4px 0 2px; }
|
||||
.formateur-row { display: flex; gap: 8px; }
|
||||
|
||||
/* TABLE FORM CONTROLS */
|
||||
.risk-table input, .risk-table textarea {
|
||||
@@ -496,6 +492,19 @@
|
||||
line-height: 1.6;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
.info-card {
|
||||
background: var(--amber-light);
|
||||
border-radius: 12px;
|
||||
padding: 16px 20px;
|
||||
max-width: 620px;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
color: var(--amber-dark);
|
||||
line-height: 1.6;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.steps-row {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
@@ -574,7 +583,7 @@
|
||||
gap: 12px;
|
||||
max-width: 640px;
|
||||
width: 100%;
|
||||
margin: 1.5rem 0;
|
||||
margin: 1.5rem auto;
|
||||
}
|
||||
.final-card {
|
||||
background: white;
|
||||
@@ -606,7 +615,7 @@
|
||||
/* SCROLLABLE AREA */
|
||||
.scroll-area {
|
||||
overflow-y: auto;
|
||||
max-height: calc(100vh - 232px);
|
||||
max-height: calc(100vh - 200px);
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -633,7 +642,7 @@
|
||||
|
||||
<!-- HEADER WITH NAVIGATION -->
|
||||
<header>
|
||||
<div class="logo">NextGN Formation</div>
|
||||
<div class="logo">Gauthier Chombart & Nathan Chauwin</div>
|
||||
<nav>
|
||||
<a href="../index.html">Accueil</a>
|
||||
<a href="../index.html#formations">Exercices</a>
|
||||
@@ -647,13 +656,14 @@
|
||||
<!-- Progress bar -->
|
||||
<div class="progress-bar"><div class="progress-fill" id="progressFill"></div></div>
|
||||
|
||||
<!-- Phase badge -->
|
||||
<div class="phase-badge" id="phaseBadge" style="display:none"></div>
|
||||
|
||||
<!-- Bottom bar -->
|
||||
<div class="bottom-bar" id="bottomBar" style="display:none;">
|
||||
<button class="back-btn" id="backBtn" onclick="goBack()" style="display:none;">← Retour</button>
|
||||
<div class="slide-counter" id="slideCounter"></div>
|
||||
<div class="bottom-actions">
|
||||
<button class="footer-btn is-secondary" id="backBtn" onclick="goBack()" style="display:none;">← Retour</button>
|
||||
<button class="footer-btn is-secondary" id="footerHintBtn" onclick="showHintCurrent()" style="display:none;">💡 Besoin d'aide ?</button>
|
||||
<button class="footer-btn is-primary" id="footerNextBtn" onclick="goNext()" style="display:none;">Étape suivante →</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal overlay -->
|
||||
@@ -666,48 +676,40 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ======================== SLIDE 0 — IDENTIFICATION ======================== -->
|
||||
<!-- ======================== SLIDE 0 — ACCUEIL ======================== -->
|
||||
<div class="slide active fade-in" id="slide-0">
|
||||
<div class="deco-circle" style="width:320px;height:320px;background:var(--amber-light);top:-80px;left:-80px;opacity:0.5;"></div>
|
||||
<div style="text-align:center; z-index:1; width:100%;">
|
||||
<div class="section-tag" style="background:var(--amber-light);color:var(--amber-dark);">Avant de commencer</div>
|
||||
<div class="slide-title">Identification du groupe</div>
|
||||
<p class="slide-intro" style="margin:0.5rem auto 0;max-width:420px;">Ces informations permettront au formateur de retrouver vos réponses.</p>
|
||||
<div class="id-form" style="margin-left:auto;margin-right:auto;">
|
||||
<div class="id-field">
|
||||
<label for="inputNom">Nom du stagiaire ou du groupe</label>
|
||||
<input type="text" id="inputNom" placeholder="Ex : Groupe 3 - Dupont / Martin" autocomplete="off">
|
||||
</div>
|
||||
<div class="id-field">
|
||||
<label for="inputDate">Date de la session</label>
|
||||
<input type="date" id="inputDate">
|
||||
</div>
|
||||
<div class="id-field">
|
||||
<label>Formateur de la session</label>
|
||||
<div style="display:flex;gap:10px;margin-top:2px;">
|
||||
<button type="button" class="formateur-btn" id="btnNathan" onclick="selectFormateur('Nathan')">Nathan</button>
|
||||
<button type="button" class="formateur-btn" id="btnGauthier" onclick="selectFormateur('Gauthier')">Gauthier</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="idError" style="color:var(--coral);font-size:13px;margin-bottom:0.5rem;display:none;">Merci de renseigner au moins le nom du groupe.</div>
|
||||
<div style="display:flex;gap:12px;justify-content:center;flex-wrap:wrap;">
|
||||
<button class="btn btn-teal" onclick="confirmIdentite()">Continuer →</button>
|
||||
<a href="correction-tp-nuisibles.html" class="btn btn-outline btn-teal">Corriger</a>
|
||||
</div>
|
||||
<div class="deco-circle" style="width:400px;height:400px;background:var(--amber-light);top:-100px;right:-80px;opacity:0.6;"></div>
|
||||
<div class="deco-circle" style="width:200px;height:200px;background:var(--amber-light);bottom:60px;left:-60px;opacity:0.5;"></div>
|
||||
<div style="text-align:center;">
|
||||
<div class="hero-label">Certibiocide — Travaux pratiques</div>
|
||||
<div class="hero-title">Étude de cas<br>Nuisibles</div>
|
||||
<p class="hero-sub">Votre mission, si vous l'acceptez : maîtriser l'identification, le traitement et la sécurité face aux nuisibles.</p>
|
||||
<button class="btn btn-amber" onclick="goTo(1)">Démarrer la mission →</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ======================== SLIDE 1 — ACCUEIL ======================== -->
|
||||
<!-- ======================== SLIDE 1 — CONTEXTE & IDENTIFICATION ======================== -->
|
||||
<div class="slide" id="slide-1">
|
||||
<div class="deco-circle" style="width:400px;height:400px;background:var(--amber-light);top:-100px;right:-80px;opacity:0.6;"></div>
|
||||
<div class="deco-circle" style="width:200px;height:200px;background:var(--amber-light);bottom:60px;left:-60px;opacity:0.5;"></div>
|
||||
<div style="text-align:center; z-index:1;">
|
||||
<div class="hero-label">Formation</div>
|
||||
<div class="hero-title">CERTIBIOCIDE</div>
|
||||
<div style="font-family:'Syne',sans-serif;font-size:clamp(14px,2.5vw,22px);font-weight:600;color:var(--amber-mid);letter-spacing:0.04em;margin-bottom:1.5rem;">TRAVAUX PRATIQUES</div>
|
||||
<p class="hero-sub">Votre mission, si vous l'acceptez : maîtriser l'identification, le traitement et la sécurité face aux nuisibles.</p>
|
||||
<button class="btn btn-teal" onclick="goTo(2)">Démarrer la mission →</button>
|
||||
<div class="deco-circle" style="width:300px;height:300px;background:var(--amber-light);top:-60px;left:-60px;opacity:0.4;"></div>
|
||||
<div class="section-tag" style="background:var(--amber-light);color:var(--amber-dark);">Avant de commencer</div>
|
||||
<div class="slide-title">Contexte & accès</div>
|
||||
<p class="slide-intro">3 travaux pratiques vous attendent : protocole d'intervention, recherche produit sur BioCID, puis analyse de risques. Ces informations permettront au formateur de retrouver vos réponses.</p>
|
||||
<div class="info-card" style="max-width:620px;">
|
||||
<span>🎯</span>
|
||||
<div>Vous allez définir un <strong>protocole d'intervention</strong>, trouver votre <strong>produit sur BioCID</strong>, puis réaliser l'<strong>analyse de risques</strong>.</div>
|
||||
</div>
|
||||
<div class="identity-card" style="max-width:620px;margin-top:0.5rem;">
|
||||
<div class="identity-title">👥 Identification du groupe</div>
|
||||
<div class="identity-fields">
|
||||
<input type="text" id="inputNom" placeholder="Nom du groupe / stagiaires (ex : Groupe 3 — Dupont / Martin)" autocomplete="off">
|
||||
<input type="date" id="inputDate">
|
||||
<div class="formateur-label">Formateur de la session</div>
|
||||
<div class="formateur-row">
|
||||
<button type="button" class="formateur-btn" id="btnNathan" onclick="selectFormateur('Nathan')">Nathan</button>
|
||||
<button type="button" class="formateur-btn" id="btnGauthier" onclick="selectFormateur('Gauthier')">Gauthier</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="idError" style="color:var(--coral);font-size:13px;margin-top:8px;display:none;">Merci de renseigner au moins le nom du groupe.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -715,8 +717,12 @@
|
||||
<div class="slide" id="slide-2">
|
||||
<div class="deco-circle" style="width:300px;height:300px;background:var(--amber-light);top:-60px;left:-60px;opacity:0.4;"></div>
|
||||
<div class="section-tag" style="background:var(--amber-light);color:var(--amber-dark);">Étape 1 / 3</div>
|
||||
<div class="slide-title">Choisissez votre mission</div>
|
||||
<div class="slide-title">🎯 Choisissez votre mission</div>
|
||||
<p class="slide-intro">Chaque groupe choisit un cas pratique. Vous travaillerez avec ce scénario tout au long des 3 exercices.</p>
|
||||
<div class="info-card" style="margin-bottom:1.25rem;">
|
||||
<span>💡</span>
|
||||
<div>Le cas retenu conditionne <strong>tous les exercices suivants</strong> et apparaît dans le PDF final. Choisissez celui qui se rapproche le plus de votre pratique.</div>
|
||||
</div>
|
||||
<div class="case-grid">
|
||||
<div class="case-card" onclick="selectCase('punaises','🛏️','Hôtel — Punaises de lit','Infestation importante dans un hôtel')">
|
||||
<div class="case-icon">🛏️</div>
|
||||
@@ -744,9 +750,6 @@
|
||||
<div class="case-sub">Camping</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actions-row">
|
||||
<button class="btn btn-teal" id="btnConfirmCase" onclick="goTo(3)" style="display:none">Confirmer le choix →</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ======================== SLIDE 3 — CONSIGNES ======================== -->
|
||||
@@ -774,7 +777,6 @@
|
||||
<span>💡</span>
|
||||
<div>À tout moment, cliquez sur <strong>« Besoin d'aide ? »</strong> pour accéder à un indice. Le formateur corrigera à l'oral en fin de séance.</div>
|
||||
</div>
|
||||
<button class="btn btn-teal" onclick="goTo(4)">Commencer le TP 1 →</button>
|
||||
</div>
|
||||
|
||||
<!-- ======================== SLIDE 4 — TP1 INTRO ======================== -->
|
||||
@@ -792,7 +794,6 @@
|
||||
<div class="step-pill">2. Intervention</div>
|
||||
<div class="step-pill">3. Évaluation</div>
|
||||
</div>
|
||||
<button class="btn btn-amber" onclick="goTo(5)">Commencer →</button>
|
||||
</div>
|
||||
|
||||
<!-- ======================== SLIDE 5 — TP1 PREVENTION ======================== -->
|
||||
@@ -833,10 +834,6 @@
|
||||
<textarea class="answer-field" id="ans_prevention_4" placeholder="Votre réponse…" data-question="Éléments observés / preuve de présence du nuisible"></textarea>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="actions-row">
|
||||
<button class="hint-btn" onclick="showHint('prevention')">💡 Besoin d'aide ?</button>
|
||||
<button class="btn btn-amber" onclick="goTo(6)">Étape suivante →</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -871,10 +868,6 @@
|
||||
<textarea class="answer-field" id="ans_intervention_3" placeholder="Votre réponse…" data-question="Type de produit (TP) et mode de traitement"></textarea>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="actions-row">
|
||||
<button class="hint-btn" onclick="showHint('intervention')">💡 Besoin d'aide ?</button>
|
||||
<button class="btn btn-amber" onclick="goTo(7)">Étape suivante →</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -905,10 +898,6 @@
|
||||
<div style="background:var(--amber-light);border-radius:12px;padding:14px 18px;max-width:680px;width:100%;font-size:13px;color:var(--amber-dark);margin:0.75rem 0;">
|
||||
✅ <strong>TP 1 terminé !</strong> Préparez-vous à identifier le produit adapté à votre cas sur biocid-anses.fr.
|
||||
</div>
|
||||
<div class="actions-row">
|
||||
<button class="hint-btn" onclick="showHint('evaluation')">💡 Besoin d'aide ?</button>
|
||||
<button class="btn btn-coral" onclick="goTo(8)">Passer au TP 2 →</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -930,7 +919,6 @@
|
||||
</div>
|
||||
<a href="https://biocid-anses.fr" target="_blank" class="resource-link">Ouvrir le site ↗</a>
|
||||
</div>
|
||||
<button class="btn btn-coral" onclick="goTo(9)">Commencer →</button>
|
||||
</div>
|
||||
|
||||
<!-- ======================== SLIDE 9 — TP2 FDS & AMM ======================== -->
|
||||
@@ -971,10 +959,6 @@
|
||||
<textarea class="answer-field" id="ans_fds_4" placeholder="Votre réponse…" data-question="Risques pour la santé"></textarea>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="actions-row">
|
||||
<button class="hint-btn" onclick="showHint('fds')">💡 Besoin d'aide ?</button>
|
||||
<button class="btn btn-coral" onclick="goTo(10)">Partie suivante →</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1019,10 +1003,6 @@
|
||||
<div style="background:var(--amber-light);border-radius:12px;padding:14px 18px;max-width:680px;width:100%;font-size:13px;color:var(--amber-dark);margin:0.75rem 0;">
|
||||
✅ <strong>TP 2 terminé !</strong> Passez maintenant à l'analyse de risques complète.
|
||||
</div>
|
||||
<div class="actions-row">
|
||||
<button class="hint-btn" onclick="showHint('epi')">💡 Besoin d'aide ?</button>
|
||||
<button class="btn btn-purple" onclick="goTo(11)">Passer au TP 3 →</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1039,9 +1019,6 @@
|
||||
<div class="pyr-level" style="width:320px;background:#D85A30;">Communication</div>
|
||||
<div class="pyr-level" style="width:360px;background:#BA7517;">EPI (dernier recours)</div>
|
||||
</div>
|
||||
<div class="actions-row" style="margin-top:1rem;">
|
||||
<button class="btn btn-purple" onclick="goTo(12)">Remplir le tableau →</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ======================== SLIDE 12 — TP3 TABLEAU ======================== -->
|
||||
@@ -1110,10 +1087,6 @@
|
||||
<div style="background:var(--amber-light);border-radius:12px;padding:14px 18px;max-width:780px;width:100%;font-size:13px;color:var(--amber-dark);margin:0.25rem 0;">
|
||||
✅ <strong>TP 3 terminé !</strong> Présentez vos réponses au formateur pour la correction.
|
||||
</div>
|
||||
<div class="actions-row">
|
||||
<button class="hint-btn" onclick="showHint('analyse')">💡 Aide générale</button>
|
||||
<button class="btn btn-blue" onclick="goTo(13)">Terminer la mission →</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1143,15 +1116,10 @@
|
||||
<div class="final-card-sub">Analyse de risques</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="submit-zone">
|
||||
<div style="display:flex;gap:10px;justify-content:center;flex-wrap:wrap;">
|
||||
<button class="btn btn-teal" onclick="exporterPDF()">⬇ Télécharger en PDF</button>
|
||||
<a href="correction-tp-nuisibles.html" class="btn btn-outline btn-teal">Corriger</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-top:0.75rem;">
|
||||
<a href="https://biocid-anses.fr" target="_blank" class="btn btn-outline btn-teal" style="font-size:13px;padding:10px 20px;">biocid-anses.fr ↗</a>
|
||||
<button class="btn btn-teal" onclick="restartAll()">↺ Recommencer depuis le début</button>
|
||||
<div class="actions-row">
|
||||
<button class="btn btn-amber" onclick="exporterPDF()">⬇ Télécharger mes réponses (PDF)</button>
|
||||
<a href="corriger-exercice.html?exo=tp" class="btn btn-outline btn-teal">✔ Corriger un rendu</a>
|
||||
<button class="btn btn-outline btn-teal" onclick="restartAll()">↺ Recommencer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1164,6 +1132,22 @@ const totalSlides = 13;
|
||||
const selectedCase = { key: '', icon: '', title: '', desc: '' };
|
||||
const stagiaire = { nom: '', date: '', formateur: '' };
|
||||
|
||||
// Configuration des boutons du footer par slide (modèle BioCID)
|
||||
const slideConfig = {
|
||||
1: { next: 2, nextLabel: 'Continuer →' },
|
||||
2: { next: 3, nextLabel: 'Confirmer le choix →' },
|
||||
3: { next: 4, nextLabel: 'Commencer le TP 1 →' },
|
||||
4: { next: 5, nextLabel: 'Commencer →' },
|
||||
5: { next: 6, nextLabel: 'Étape suivante →', hint: 'prevention' },
|
||||
6: { next: 7, nextLabel: 'Étape suivante →', hint: 'intervention' },
|
||||
7: { next: 8, nextLabel: 'Passer au TP 2 →', hint: 'evaluation' },
|
||||
8: { next: 9, nextLabel: 'Commencer →' },
|
||||
9: { next: 10, nextLabel: 'Partie suivante →', hint: 'fds' },
|
||||
10: { next: 11, nextLabel: 'Passer au TP 3 →', hint: 'epi' },
|
||||
11: { next: 12, nextLabel: 'Remplir le tableau →' },
|
||||
12: { next: 13, nextLabel: 'Terminer la mission →', hint: 'analyse' }
|
||||
};
|
||||
|
||||
const hints = {
|
||||
prevention: {
|
||||
icon: '💡',
|
||||
@@ -1250,11 +1234,28 @@ function goTo(n) {
|
||||
currentSlide = n;
|
||||
next.style.display = 'flex';
|
||||
setTimeout(() => { next.classList.add('active', 'fade-in'); }, 10);
|
||||
const sa = next.querySelector('.scroll-area');
|
||||
if (sa) sa.scrollTop = 0;
|
||||
if (n === 13) setTimeout(launchConfetti, 200);
|
||||
updateUI();
|
||||
updateCaseBanners();
|
||||
}
|
||||
|
||||
function goNext() {
|
||||
const cfg = slideConfig[currentSlide];
|
||||
if (!cfg || cfg.next == null) return;
|
||||
// Slide 1 : validation du nom du groupe avant de continuer
|
||||
if (currentSlide === 1) { confirmIdentite(); return; }
|
||||
// Slide 2 : un cas doit être sélectionné
|
||||
if (currentSlide === 2 && !selectedCase.key) return;
|
||||
goTo(cfg.next);
|
||||
}
|
||||
|
||||
function showHintCurrent() {
|
||||
const cfg = slideConfig[currentSlide];
|
||||
if (cfg && cfg.hint) showHint(cfg.hint);
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
if (history.length === 0) return;
|
||||
const prev = history.pop();
|
||||
@@ -1279,37 +1280,31 @@ function updateUI() {
|
||||
if (bottomBar) bottomBar.style.display = currentSlide === 0 ? 'none' : 'flex';
|
||||
|
||||
const backBtn = document.getElementById('backBtn');
|
||||
backBtn.style.display = history.length > 0 ? 'block' : 'none';
|
||||
backBtn.style.display = history.length > 0 ? 'inline-flex' : 'none';
|
||||
|
||||
const badge = document.getElementById('phaseBadge');
|
||||
if (currentSlide === 0 || currentSlide === 1 || currentSlide === 2 || currentSlide === 3 || currentSlide === 13) {
|
||||
badge.style.display = 'none';
|
||||
} else if (currentSlide >= 4 && currentSlide <= 7) {
|
||||
badge.style.display = 'block';
|
||||
badge.style.background = 'var(--amber-light)';
|
||||
badge.style.color = 'var(--amber-dark)';
|
||||
badge.textContent = 'TP 1 — Protocole';
|
||||
} else if (currentSlide >= 8 && currentSlide <= 10) {
|
||||
badge.style.display = 'block';
|
||||
badge.style.background = 'var(--coral-light)';
|
||||
badge.style.color = 'var(--coral)';
|
||||
badge.textContent = 'TP 2 — Produit';
|
||||
} else if (currentSlide >= 11 && currentSlide <= 12) {
|
||||
badge.style.display = 'block';
|
||||
badge.style.background = 'var(--amber-light)';
|
||||
badge.style.color = 'var(--amber-dark)';
|
||||
badge.textContent = 'TP 3 — Risques';
|
||||
const cfg = slideConfig[currentSlide] || {};
|
||||
const hintBtn = document.getElementById('footerHintBtn');
|
||||
const nextBtn = document.getElementById('footerNextBtn');
|
||||
hintBtn.style.display = cfg.hint ? 'inline-flex' : 'none';
|
||||
if (cfg.next != null) {
|
||||
// Slide 2 : le bouton n'apparaît qu'une fois le cas choisi
|
||||
const gated = currentSlide === 2 && !selectedCase.key;
|
||||
nextBtn.style.display = gated ? 'none' : 'inline-flex';
|
||||
nextBtn.textContent = cfg.nextLabel;
|
||||
} else {
|
||||
nextBtn.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function selectCase(key, icon, title, desc) {
|
||||
marquerModifie();
|
||||
selectedCase.key = key;
|
||||
selectedCase.icon = icon;
|
||||
selectedCase.title = title;
|
||||
selectedCase.desc = desc;
|
||||
document.querySelectorAll('.case-card').forEach(c => c.classList.remove('selected'));
|
||||
event.currentTarget.classList.add('selected');
|
||||
document.getElementById('btnConfirmCase').style.display = 'inline-flex';
|
||||
updateUI();
|
||||
}
|
||||
|
||||
function updateCaseBanners() {
|
||||
@@ -1379,7 +1374,7 @@ function confirmIdentite() {
|
||||
document.getElementById('idError').style.display = 'none';
|
||||
stagiaire.nom = nom;
|
||||
stagiaire.date = date || new Date().toISOString().slice(0, 10);
|
||||
goTo(1);
|
||||
goTo(2);
|
||||
}
|
||||
|
||||
/* ======================== TABLEAU TP3 — LIGNES DYNAMIQUES ======================== */
|
||||
@@ -1606,6 +1601,156 @@ function escapeHtml(str) {
|
||||
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
}
|
||||
|
||||
/* ======================== SAUVEGARDE AUTOMATIQUE ======================== */
|
||||
/* Les réponses sont enregistrées dans le navigateur au fil de la saisie, puis
|
||||
proposées à la restauration au rechargement. En file://, localStorage peut être
|
||||
indisponible (Safari) : dans ce cas la page fonctionne normalement, sans filet. */
|
||||
const CLE_SAUVEGARDE = 'certibiocide:tp-nuisibles:v1';
|
||||
|
||||
let reponsesModifiees = false;
|
||||
function marquerModifie() { reponsesModifiees = true; sauvegarder(); }
|
||||
|
||||
document.addEventListener('input', marquerModifie, true);
|
||||
document.addEventListener('change', marquerModifie, true);
|
||||
|
||||
// Avertit avant tout rechargement ou départ. Le texte de la boîte est imposé
|
||||
// par le navigateur, il n'est pas personnalisable.
|
||||
window.addEventListener('beforeunload', e => {
|
||||
if (!reponsesModifiees) return;
|
||||
e.preventDefault();
|
||||
e.returnValue = '';
|
||||
});
|
||||
|
||||
function etatCourant() {
|
||||
const champs = {};
|
||||
document.querySelectorAll('input[id], textarea[id]').forEach(el => {
|
||||
if (el.value) champs[el.id] = el.value;
|
||||
});
|
||||
// Les cellules du tableau TP3 n'ont pas d'id : on les repère par leur position.
|
||||
const risques = Array.from(document.querySelectorAll('#riskTableBody .risk-row'))
|
||||
.map(row => Array.from(row.querySelectorAll('.risk-cell')).map(c => c.value));
|
||||
|
||||
return {
|
||||
savedAt: new Date().toISOString(),
|
||||
slide: currentSlide,
|
||||
champs,
|
||||
risques,
|
||||
cas: selectedCase.key || '',
|
||||
formateur: stagiaire.formateur || '',
|
||||
nom: stagiaire.nom || '',
|
||||
date: stagiaire.date || '',
|
||||
};
|
||||
}
|
||||
|
||||
let minuteurSauvegarde = null;
|
||||
function sauvegarder() {
|
||||
clearTimeout(minuteurSauvegarde);
|
||||
minuteurSauvegarde = setTimeout(() => {
|
||||
try {
|
||||
localStorage.setItem(CLE_SAUVEGARDE, JSON.stringify(etatCourant()));
|
||||
} catch (e) { /* navigation privée ou quota : on continue sans sauvegarde */ }
|
||||
}, 400);
|
||||
}
|
||||
|
||||
function lireSauvegarde() {
|
||||
try { return JSON.parse(localStorage.getItem(CLE_SAUVEGARDE)); }
|
||||
catch (e) { return null; }
|
||||
}
|
||||
function effacerSauvegarde() {
|
||||
try { localStorage.removeItem(CLE_SAUVEGARDE); } catch (e) {}
|
||||
}
|
||||
|
||||
function appliquerSauvegarde(data) {
|
||||
Object.entries(data.champs || {}).forEach(([id, v]) => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.value = v;
|
||||
});
|
||||
|
||||
// Recrée autant de lignes de risques que nécessaire avant de les remplir
|
||||
const risques = data.risques || [];
|
||||
const tbody = document.getElementById('riskTableBody');
|
||||
while (tbody.querySelectorAll('.risk-row').length < risques.length) addRiskRow();
|
||||
tbody.querySelectorAll('.risk-row').forEach((row, i) => {
|
||||
const valeurs = risques[i] || [];
|
||||
row.querySelectorAll('.risk-cell').forEach((cell, j) => { cell.value = valeurs[j] || ''; });
|
||||
});
|
||||
|
||||
// Le cas pratique et le formateur passent par leurs boutons, qui remettent
|
||||
// aussi l'interface (carte sélectionnée, bouton de confirmation) dans le bon état.
|
||||
if (data.cas) {
|
||||
const carte = Array.from(document.querySelectorAll('.case-card'))
|
||||
.find(c => (c.getAttribute('onclick') || '').includes("'" + data.cas + "'"));
|
||||
if (carte) carte.click();
|
||||
}
|
||||
if (data.formateur) {
|
||||
const btn = document.getElementById('btn' + data.formateur);
|
||||
if (btn) btn.click();
|
||||
}
|
||||
stagiaire.nom = data.nom || stagiaire.nom;
|
||||
stagiaire.date = data.date || stagiaire.date;
|
||||
|
||||
reponsesModifiees = true;
|
||||
if (typeof data.slide === 'number' && data.slide > 0) goTo(data.slide);
|
||||
updateUI();
|
||||
}
|
||||
|
||||
/* Bandeau de restauration : on ne restaure jamais sans demander, pour qu'un
|
||||
nouveau groupe n'hérite pas des réponses du précédent sur un poste partagé. */
|
||||
function injecterStylesBandeau() {
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
.restore-bar {
|
||||
position: fixed; top: 84px; left: 50%; transform: translateX(-50%);
|
||||
z-index: 900; max-width: min(680px, calc(100vw - 32px));
|
||||
display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
|
||||
background: var(--white); border: 1.5px solid var(--amber);
|
||||
border-radius: 14px; padding: 14px 18px;
|
||||
box-shadow: 0 8px 28px rgba(0,0,0,0.12); font-size: 13.5px;
|
||||
}
|
||||
.restore-bar .restore-text { flex: 1; min-width: 220px; line-height: 1.5; }
|
||||
.restore-bar .restore-actions { display: flex; gap: 8px; flex-shrink: 0; }
|
||||
.restore-bar button {
|
||||
font-family: 'Syne', sans-serif; font-weight: 700; font-size: 12.5px;
|
||||
padding: 8px 16px; border-radius: 20px; cursor: pointer;
|
||||
border: 1px solid var(--border); background: transparent; color: var(--text-muted);
|
||||
}
|
||||
.restore-bar button:hover { border-color: var(--amber); color: var(--amber); }
|
||||
.restore-bar button.primary {
|
||||
background: var(--amber); border-color: var(--amber); color: #fff;
|
||||
}
|
||||
.restore-bar button.primary:hover { background: var(--amber-dark); border-color: var(--amber-dark); color: #fff; }
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
function proposerRestauration() {
|
||||
const data = lireSauvegarde();
|
||||
if (!data) return;
|
||||
const aDesReponses = (data.champs && Object.keys(data.champs).length > 0)
|
||||
|| (data.risques || []).some(r => r.some(v => v));
|
||||
if (!aDesReponses) return;
|
||||
|
||||
const quand = new Date(data.savedAt);
|
||||
const libelle = isNaN(quand.getTime()) ? '' :
|
||||
` du ${quand.toLocaleDateString('fr-FR')} à ${quand.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' })}`;
|
||||
|
||||
injecterStylesBandeau();
|
||||
const bar = document.createElement('div');
|
||||
bar.className = 'restore-bar';
|
||||
bar.innerHTML = `
|
||||
<span class="restore-text">💾 Des réponses enregistrées${libelle} ont été retrouvées sur ce poste.</span>
|
||||
<span class="restore-actions">
|
||||
<button type="button" class="primary" id="btnRestaurer">Restaurer</button>
|
||||
<button type="button" id="btnRepartir">Repartir de zéro</button>
|
||||
</span>`;
|
||||
document.body.appendChild(bar);
|
||||
|
||||
document.getElementById('btnRestaurer').onclick = () => { appliquerSauvegarde(data); bar.remove(); };
|
||||
document.getElementById('btnRepartir').onclick = () => { effacerSauvegarde(); bar.remove(); };
|
||||
}
|
||||
|
||||
proposerRestauration();
|
||||
|
||||
updateUI();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -1,650 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Correction TP Nuisibles — Certibiocide</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@600;700;800&family=DM+Sans:ital,wght@0,400;0,500;1,400&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="../header-style.css"/>
|
||||
<style>
|
||||
body {
|
||||
padding: calc(36px + 70px) 20px 80px;
|
||||
}
|
||||
.wrap { max-width: 820px; margin: 0 auto; }
|
||||
.syne { font-family: 'Syne', sans-serif; }
|
||||
.eyebrow {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: var(--amber);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
h1 {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 28px;
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.5px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
/* DROPZONE */
|
||||
#dropzone {
|
||||
background: #fff;
|
||||
border: 2px dashed rgba(186,117,23,0.35);
|
||||
border-radius: 16px;
|
||||
padding: 56px 24px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s, background 0.2s;
|
||||
}
|
||||
#dropzone.drag { border-color: var(--amber); background: var(--amber-light); }
|
||||
#dropzone .icon { font-size: 40px; margin-bottom: 12px; }
|
||||
#dropzone p.title { font-family: 'Syne', sans-serif; font-weight: 700; font-size: 16px; margin-bottom: 6px; }
|
||||
#dropzone p.sub { color: var(--text-muted); font-size: 13.5px; margin-bottom: 20px; }
|
||||
#filePicker { display: none; }
|
||||
.btn-pick {
|
||||
font-family: 'Syne', sans-serif;
|
||||
display: inline-block;
|
||||
background: var(--amber);
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
font-size: 13px;
|
||||
padding: 10px 26px;
|
||||
border-radius: 30px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
}
|
||||
#status { margin-top: 16px; font-size: 13px; }
|
||||
#status.loading { color: var(--amber); }
|
||||
#status.error { color: var(--coral); }
|
||||
|
||||
/* RESULT */
|
||||
#result { display: none; }
|
||||
.toprow {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
#fileName { font-size: 12.5px; color: var(--text-muted); }
|
||||
.btn-reset {
|
||||
font-family: 'Syne', sans-serif;
|
||||
background: transparent;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 20px;
|
||||
padding: 6px 16px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.btn-reset:hover { border-color: var(--amber); color: var(--amber); }
|
||||
|
||||
.id-card { display: none; }
|
||||
|
||||
/* BANDEAU PARTICIPANTS */
|
||||
#participantsBanner {
|
||||
background: linear-gradient(135deg, var(--amber) 0%, #D8923A 100%);
|
||||
border-radius: 16px;
|
||||
padding: 20px 26px;
|
||||
margin-bottom: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
color: #fff;
|
||||
}
|
||||
#participantsBanner .pb-icon {
|
||||
width: 48px; height: 48px;
|
||||
border-radius: 12px;
|
||||
background: rgba(255,255,255,0.2);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
#participantsBanner .pb-group {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
opacity: 0.85;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
#participantsBanner .pb-names {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.id-card .label {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 10.5px;
|
||||
font-weight: 700;
|
||||
color: var(--amber-dark);
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.id-card .value { font-size: 14.5px; margin-top: 2px; }
|
||||
|
||||
.progress-row { display: flex; align-items: center; gap: 10px; margin-bottom: 30px; font-size: 13px; color: var(--text-muted); }
|
||||
.progress-track { flex: 1; height: 7px; background: rgba(0,0,0,0.08); border-radius: 6px; overflow: hidden; }
|
||||
.progress-fill { height: 100%; background: var(--teal); transition: width 0.4s ease; }
|
||||
.progress-row strong { font-family: 'Syne', sans-serif; color: var(--text); }
|
||||
|
||||
/* CARROUSEL DE THEMES */
|
||||
.carousel-wrap { margin-bottom: 36px; }
|
||||
.carousel-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.nav-btn {
|
||||
width: 38px; height: 38px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--border);
|
||||
background: #fff;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
transition: background 0.15s, border-color 0.15s;
|
||||
}
|
||||
.nav-btn:hover { background: var(--amber-light); border-color: var(--amber); }
|
||||
.nav-btn:disabled { opacity: 0.3; cursor: default; }
|
||||
.nav-btn:disabled:hover { background: #fff; border-color: var(--border); }
|
||||
.dots { display: flex; gap: 7px; }
|
||||
.dot { width: 8px; height: 8px; border-radius: 50%; background: rgba(0,0,0,0.15); cursor: pointer; transition: background 0.15s, transform 0.15s; }
|
||||
.dot.active { background: var(--amber); transform: scale(1.3); }
|
||||
|
||||
.theme-panel {
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 18px;
|
||||
padding: 26px 28px;
|
||||
min-height: 420px;
|
||||
}
|
||||
.theme-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.theme-icon {
|
||||
width: 44px; height: 44px;
|
||||
border-radius: 12px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 22px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.theme-title { font-family: 'Syne', sans-serif; font-weight: 800; font-size: 17px; }
|
||||
.theme-count { font-size: 12.5px; color: var(--text-muted); margin-left: auto; }
|
||||
|
||||
.cards { display: flex; flex-direction: column; gap: 10px; }
|
||||
.qcard {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 14px 18px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
transition: box-shadow 0.2s;
|
||||
}
|
||||
.qcard:hover { box-shadow: 0 4px 16px rgba(0,0,0,0.06); }
|
||||
.qcard .badge {
|
||||
width: 22px; height: 22px;
|
||||
border-radius: 50%;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 12px;
|
||||
flex-shrink: 0;
|
||||
margin-top: 1px;
|
||||
}
|
||||
.qcard .badge.ok { background: var(--teal-light); color: var(--teal); }
|
||||
.qcard .badge.miss { background: var(--coral-light); color: var(--coral); }
|
||||
.qcard .qtext { flex: 1; }
|
||||
.qcard .qlabel { font-weight: 600; font-size: 13.5px; margin-bottom: 4px; }
|
||||
.qcard .qanswer { font-size: 13.5px; white-space: pre-wrap; }
|
||||
.qcard .qanswer.empty { color: var(--coral); font-style: italic; }
|
||||
|
||||
.table-wrap {
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 16px 18px;
|
||||
font-size: 13px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
/* TABLEAU ANALYSE DE RISQUES */
|
||||
.risk-table { width: 100%; border-collapse: collapse; font-size: 13px; }
|
||||
.risk-table th {
|
||||
font-family: 'Syne', sans-serif;
|
||||
text-align: left;
|
||||
font-size: 11.5px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--amber-dark);
|
||||
background: var(--amber-light);
|
||||
padding: 10px 12px;
|
||||
}
|
||||
.risk-table th:first-child { border-radius: 8px 0 0 8px; }
|
||||
.risk-table th:last-child { border-radius: 0 8px 8px 0; }
|
||||
.risk-table td {
|
||||
padding: 10px 12px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
vertical-align: top;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.risk-table tr:last-child td { border-bottom: none; }
|
||||
.meta-line { font-size: 12.5px; color: var(--text-muted); margin-top: 20px; }
|
||||
.meta-line strong { color: var(--text); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="logo">NextGN Formation</div>
|
||||
<nav>
|
||||
<a href="../index.html">Accueil</a>
|
||||
<a href="../index.html#formations">Exercices</a>
|
||||
<a href="../index.html#documentation">Documentation</a>
|
||||
<a href="../index.html#rapports">Rapports</a>
|
||||
<a href="../index.html#about">À propos</a>
|
||||
<a href="../index.html#contact">Contact</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
<div id="participantsBanner" style="display:none;"></div>
|
||||
<div class="eyebrow">Certibiocide — Correction de TP</div>
|
||||
<h1>TP Nuisibles — Lecture du rendu</h1>
|
||||
|
||||
<div id="dropzone">
|
||||
<div class="icon">📄</div>
|
||||
<p class="title">Déposez le PDF du stagiaire ici</p>
|
||||
<p class="sub">ou cliquez pour sélectionner le fichier exporté depuis le TP</p>
|
||||
<label class="btn-pick">Choisir un fichier
|
||||
<input type="file" id="filePicker" accept="application/pdf">
|
||||
</label>
|
||||
<div id="status"></div>
|
||||
</div>
|
||||
|
||||
<div id="result">
|
||||
<div class="toprow">
|
||||
<span id="fileName"></span>
|
||||
<button class="btn-reset" onclick="resetAll()">↺ Charger un autre PDF</button>
|
||||
</div>
|
||||
|
||||
<div class="id-card" id="idCard"></div>
|
||||
|
||||
<div class="progress-row">
|
||||
<div class="progress-track"><div class="progress-fill" id="progressFill"></div></div>
|
||||
<span><strong id="progressCount"></strong> questions répondues</span>
|
||||
</div>
|
||||
|
||||
<div class="carousel-wrap">
|
||||
<div class="carousel-nav">
|
||||
<button class="nav-btn" id="prevBtn" onclick="goTo(currentTheme - 1)">←</button>
|
||||
<div class="dots" id="dots"></div>
|
||||
<button class="nav-btn" id="nextBtn" onclick="goTo(currentTheme + 1)">→</button>
|
||||
</div>
|
||||
<div id="themePanel"></div>
|
||||
</div>
|
||||
|
||||
<h2 class="syne" style="font-size:16px;font-weight:800;margin-bottom:12px;color:var(--amber-dark);">Analyse de risques</h2>
|
||||
<div class="table-wrap" id="tp3Meta"></div>
|
||||
<div class="table-wrap" id="tp3Table" style="display:none;"></div>
|
||||
<p class="meta-line" id="suiviLine"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>© 2026 NextGN Formation - Formations Certibiocide & Techniques</p>
|
||||
<p style="margin-top: 10px; opacity: 0.6;">Tous droits réservés — Gauthier Chombart & Nathan Chauwin — Formateurs indépendants</p>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
|
||||
<script>
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js";
|
||||
|
||||
// Thèmes regroupant les sections du TP, avec icône et couleur
|
||||
const THEMES = [
|
||||
{
|
||||
title: "Premier contact & diagnostic",
|
||||
icon: "🗣️", color: "purple",
|
||||
items: [
|
||||
"Questions posées au client lors du premier contact",
|
||||
"Conseils donnés en premier lieu",
|
||||
"Actions de prévention menées sur le site",
|
||||
"Éléments observés / preuve de présence du nuisible",
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Solutions envisagées",
|
||||
icon: "🧰", color: "blue",
|
||||
items: [
|
||||
"Solutions alternatives non-biocides",
|
||||
"Solutions biocides mises en place",
|
||||
"Type de produit (TP) et mode de traitement",
|
||||
"Suivi mis en place et durée",
|
||||
"Gestion des déchets",
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Produit & traçabilité",
|
||||
icon: "🧪", color: "teal",
|
||||
items: [
|
||||
"FDS trouvée (éléments principaux)",
|
||||
"Nom du produit et fabricant/fournisseur",
|
||||
"Numéro AMM",
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Sécurité & santé",
|
||||
icon: "🛡️", color: "coral",
|
||||
items: [
|
||||
"Risques pour la santé",
|
||||
"EPI à porter",
|
||||
"Risques environnement / dispersion accidentelle",
|
||||
"DL50 substance(s) active(s)",
|
||||
"Gestes de premiers secours",
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
const ALL_SECTIONS = THEMES.flatMap(t => t.items);
|
||||
|
||||
const COLOR_MAP = {
|
||||
purple: { bg: "var(--purple-light)", fg: "var(--purple)" },
|
||||
blue: { bg: "var(--blue-light)", fg: "var(--blue)" },
|
||||
teal: { bg: "var(--teal-light)", fg: "var(--teal)" },
|
||||
coral: { bg: "var(--coral-light)", fg: "var(--coral)" },
|
||||
};
|
||||
|
||||
function escapeRx(s) { return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); }
|
||||
function escapeHtml(s) {
|
||||
if (!s) return "";
|
||||
return s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
||||
}
|
||||
function isEmpty(v) {
|
||||
if (!v) return true;
|
||||
const t = v.trim();
|
||||
return t === "" || /^\(sans réponse\)$/i.test(t);
|
||||
}
|
||||
|
||||
function captureBetween(text, label, nextLabels) {
|
||||
const startRx = new RegExp(escapeRx(label) + "\\s*:?\\s*", "i");
|
||||
const m = startRx.exec(text);
|
||||
if (!m) return "";
|
||||
const from = m.index + m[0].length;
|
||||
let to = text.length;
|
||||
for (const nl of nextLabels) {
|
||||
const endRx = new RegExp(escapeRx(nl), "i");
|
||||
const m2 = endRx.exec(text.slice(from));
|
||||
if (m2 && from + m2.index < to) to = from + m2.index;
|
||||
}
|
||||
return text.slice(from, to).trim();
|
||||
}
|
||||
|
||||
function parsePdfText(raw) {
|
||||
let clean = raw.replace(/\r/g, "").replace(/[ \t]+\n/g, "\n").replace(/\s+/g, " ").trim();
|
||||
// Retire les répétitions d'en-tête de page (ex: "17/06/2026 15:42 Résultats TP — ... about:blank 1/2")
|
||||
clean = clean.replace(/\d{1,2}\/\d{1,2}\/\d{4}\s+\d{1,2}:\d{2}\s+Résultats TP[^]*?about:blank\s*\d\/\d/gi, " ");
|
||||
|
||||
const meta = {
|
||||
nom: captureBetween(clean, "Groupe / Stagiaire", ["Date de session"]),
|
||||
date_session: captureBetween(clean, "Date de session", ["Formateur"]),
|
||||
formateur: captureBetween(clean, "Formateur", ["Cas pratique"]),
|
||||
cas: captureBetween(clean, "Cas pratique", ["Réponses TP1"]),
|
||||
};
|
||||
|
||||
// Sépare "Groupe N" du nom des participants (ex: "Groupe 1 Romain Kevin Valere Greg P")
|
||||
const groupMatch = /^Groupe\s*(\d+)\s*(.*)$/i.exec(meta.nom.trim());
|
||||
if (groupMatch) {
|
||||
meta.groupe = "Groupe " + groupMatch[1];
|
||||
meta.participants = groupMatch[2].trim();
|
||||
} else {
|
||||
meta.groupe = "";
|
||||
meta.participants = meta.nom.trim();
|
||||
}
|
||||
|
||||
const startIdx = clean.search(/Réponses TP1\s*&?\s*TP2/i);
|
||||
const endIdx = clean.search(/TP3\s*[—-]\s*Analyse de risques/i);
|
||||
const block = startIdx >= 0 ? clean.slice(startIdx, endIdx >= 0 ? endIdx : clean.length) : clean;
|
||||
|
||||
const answers = {};
|
||||
for (let i = 0; i < ALL_SECTIONS.length; i++) {
|
||||
const label = ALL_SECTIONS[i];
|
||||
const nextLabel = ALL_SECTIONS[i + 1];
|
||||
answers[label] = captureBetween(block, label, nextLabel ? [nextLabel] : []);
|
||||
}
|
||||
|
||||
const tp3Zone = endIdx >= 0 ? clean.slice(endIdx) : "";
|
||||
const tp3 = {
|
||||
intitule: captureBetween(tp3Zone, "Intitulé", ["Description"]),
|
||||
description: captureBetween(tp3Zone, "Description", ["Lieu"]),
|
||||
lieu: captureBetween(tp3Zone, "Lieu", ["Début prévu le"]),
|
||||
debut: captureBetween(tp3Zone, "Début prévu le", ["Étapes"]),
|
||||
};
|
||||
|
||||
// Tableau de risques : on découpe en s'appuyant sur les intitulés d'étapes connus du TP
|
||||
const KNOWN_STEPS = [
|
||||
"remplir la poudreuse",
|
||||
"sécurisation du site",
|
||||
"application traitements",
|
||||
"rangement du matériel. purger la perche",
|
||||
"retrait du nid",
|
||||
"gestion des déchets. élimination par des filiaires spé.",
|
||||
];
|
||||
let riskRows = [];
|
||||
const tableMatch = /Étapes\s*Risques\s*Mesures de prévention([\s\S]*?)(Réalisée par|$)/i.exec(tp3Zone);
|
||||
if (tableMatch) {
|
||||
let raw = tableMatch[1].trim();
|
||||
if (raw) {
|
||||
// Repère les positions de chaque étape connue dans le texte aplati
|
||||
const positions = [];
|
||||
KNOWN_STEPS.forEach(step => {
|
||||
const idx = raw.toLowerCase().indexOf(step.toLowerCase());
|
||||
if (idx >= 0) positions.push({ step, idx });
|
||||
});
|
||||
positions.sort((a, b) => a.idx - b.idx);
|
||||
|
||||
if (positions.length > 0) {
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
const from = positions[i].idx + positions[i].step.length;
|
||||
const to = i + 1 < positions.length ? positions[i + 1].idx : raw.length;
|
||||
let rest = raw.slice(from, to).trim();
|
||||
// rest contient "risque... mesure..." -> on coupe sur les mots clés de mesures (gants/masques, barrieres, etc.)
|
||||
const measureRx = /(gants\s*\/\s*masques\s*\/\s*lunettes[^.]*|barrieres\.?\s*epi)/i;
|
||||
const mm = measureRx.exec(rest);
|
||||
let risque = rest, mesure = "";
|
||||
if (mm) {
|
||||
risque = rest.slice(0, mm.index).trim();
|
||||
mesure = rest.slice(mm.index).trim();
|
||||
}
|
||||
risque = risque.replace(/^[\s\-–.]+/, "").trim();
|
||||
riskRows.push({ etape: positions[i].step, risque: risque || "—", mesure: mesure || "—" });
|
||||
}
|
||||
} else {
|
||||
riskRows.push({ etape: raw, risque: "", mesure: "" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const mReal = clean.match(/Réalisée par\s*:\s*([^—\n]*)/i);
|
||||
const mVerif = clean.match(/Vérifiée par\s*:\s*([^—\n]*)/i);
|
||||
const mMaj = clean.match(/Mise à jour par\s*:\s*([^—\n]*)/i);
|
||||
|
||||
return {
|
||||
meta, answers, tp3, riskRows,
|
||||
suivi: {
|
||||
realise: mReal ? mReal[1].trim() : "",
|
||||
verifie: mVerif ? mVerif[1].trim() : "",
|
||||
maj: mMaj ? mMaj[1].trim() : "",
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let currentThemeData = null;
|
||||
let currentTheme = 0;
|
||||
|
||||
function renderThemePanel() {
|
||||
const theme = THEMES[currentTheme];
|
||||
const data = currentThemeData;
|
||||
const colors = COLOR_MAP[theme.color];
|
||||
const themeAnswered = theme.items.filter(s => !isEmpty(data.answers[s])).length;
|
||||
|
||||
document.getElementById("themePanel").innerHTML = `
|
||||
<div class="theme-panel">
|
||||
<div class="theme-head">
|
||||
<div class="theme-icon" style="background:${colors.bg};color:${colors.fg};">${theme.icon}</div>
|
||||
<div class="theme-title">${theme.title}</div>
|
||||
<div class="theme-count">${themeAnswered}/${theme.items.length}</div>
|
||||
</div>
|
||||
<div class="cards">
|
||||
${theme.items.map(label => {
|
||||
const value = data.answers[label] || "";
|
||||
const empty = isEmpty(value);
|
||||
return `
|
||||
<div class="qcard">
|
||||
<div class="badge ${empty ? 'miss' : 'ok'}">${empty ? '!' : '✓'}</div>
|
||||
<div class="qtext">
|
||||
<div class="qlabel">${escapeHtml(label)}</div>
|
||||
<div class="qanswer ${empty ? 'empty' : ''}">${empty ? 'Sans réponse' : escapeHtml(value)}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}).join("")}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.getElementById("prevBtn").disabled = currentTheme === 0;
|
||||
document.getElementById("nextBtn").disabled = currentTheme === THEMES.length - 1;
|
||||
document.querySelectorAll(".dot").forEach((d, i) => d.classList.toggle("active", i === currentTheme));
|
||||
}
|
||||
|
||||
function goTo(idx) {
|
||||
if (idx < 0 || idx >= THEMES.length) return;
|
||||
currentTheme = idx;
|
||||
renderThemePanel();
|
||||
}
|
||||
|
||||
function renderResult(data) {
|
||||
currentThemeData = data;
|
||||
currentTheme = 0;
|
||||
|
||||
const banner = document.getElementById("participantsBanner");
|
||||
if (data.meta.participants) {
|
||||
banner.style.display = "flex";
|
||||
banner.innerHTML = `
|
||||
<div class="pb-icon">👥</div>
|
||||
<div>
|
||||
<div class="pb-group">${escapeHtml(data.meta.groupe) || "Participants"}</div>
|
||||
<div class="pb-names">${escapeHtml(data.meta.participants)}</div>
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
banner.style.display = "none";
|
||||
}
|
||||
|
||||
document.getElementById("idCard").innerHTML = `
|
||||
<div><div class="label">Groupe / Stagiaire</div><div class="value">${escapeHtml(data.meta.nom) || "—"}</div></div>
|
||||
<div><div class="label">Date de session</div><div class="value">${escapeHtml(data.meta.date_session) || "—"}</div></div>
|
||||
<div><div class="label">Formateur</div><div class="value">${escapeHtml(data.meta.formateur) || "—"}</div></div>
|
||||
<div><div class="label">Cas pratique</div><div class="value">${escapeHtml(data.meta.cas) || "—"}</div></div>
|
||||
`;
|
||||
|
||||
const answeredCount = ALL_SECTIONS.filter(s => !isEmpty(data.answers[s])).length;
|
||||
document.getElementById("progressFill").style.width = (answeredCount / ALL_SECTIONS.length * 100) + "%";
|
||||
document.getElementById("progressCount").textContent = `${answeredCount} / ${ALL_SECTIONS.length}`;
|
||||
|
||||
document.getElementById("dots").innerHTML = THEMES.map((_, i) =>
|
||||
`<div class="dot${i === 0 ? ' active' : ''}" onclick="goTo(${i})"></div>`
|
||||
).join("");
|
||||
|
||||
renderThemePanel();
|
||||
|
||||
document.getElementById("tp3Meta").innerHTML = `
|
||||
<p style="margin-bottom:6px;"><strong>Intitulé :</strong> ${escapeHtml(data.tp3.intitule) || '<em style="color:var(--coral)">—</em>'}</p>
|
||||
<p style="margin-bottom:6px;"><strong>Description :</strong> ${escapeHtml(data.tp3.description) || '<em style="color:var(--coral)">—</em>'}</p>
|
||||
<p style="margin-bottom:6px;"><strong>Lieu :</strong> ${escapeHtml(data.tp3.lieu) || '<em style="color:var(--coral)">—</em>'}</p>
|
||||
<p><strong>Début prévu le :</strong> ${escapeHtml(data.tp3.debut) || '<em style="color:var(--coral)">—</em>'}</p>
|
||||
`;
|
||||
|
||||
const tp3TableEl = document.getElementById("tp3Table");
|
||||
if (data.riskRows && data.riskRows.length > 0) {
|
||||
tp3TableEl.style.display = "block";
|
||||
tp3TableEl.innerHTML = `
|
||||
<table class="risk-table">
|
||||
<thead><tr><th>Étapes</th><th>Risques</th><th>Mesures de prévention</th></tr></thead>
|
||||
<tbody>
|
||||
${data.riskRows.map(r => `
|
||||
<tr>
|
||||
<td>${escapeHtml(r.etape) || "—"}</td>
|
||||
<td>${escapeHtml(r.risque) || "—"}</td>
|
||||
<td>${escapeHtml(r.mesure) || "—"}</td>
|
||||
</tr>
|
||||
`).join("")}
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
} else {
|
||||
tp3TableEl.style.display = "none";
|
||||
}
|
||||
|
||||
document.getElementById("suiviLine").innerHTML =
|
||||
`Réalisée par : <strong>${escapeHtml(data.suivi.realise) || "—"}</strong> — Vérifiée par : <strong>${escapeHtml(data.suivi.verifie) || "—"}</strong> — Mise à jour par : <strong>${escapeHtml(data.suivi.maj) || "—"}</strong>`;
|
||||
|
||||
document.getElementById("dropzone").style.display = "none";
|
||||
document.getElementById("result").style.display = "block";
|
||||
}
|
||||
|
||||
async function handleFile(file) {
|
||||
if (!file) return;
|
||||
const statusEl = document.getElementById("status");
|
||||
statusEl.className = "loading";
|
||||
statusEl.textContent = "Lecture du PDF en cours…";
|
||||
document.getElementById("fileName").textContent = file.name;
|
||||
|
||||
try {
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;
|
||||
let fullText = "";
|
||||
for (let p = 1; p <= pdf.numPages; p++) {
|
||||
const page = await pdf.getPage(p);
|
||||
const content = await page.getTextContent();
|
||||
fullText += content.items.map(it => it.str).join(" ") + "\n";
|
||||
}
|
||||
const data = parsePdfText(fullText);
|
||||
renderResult(data);
|
||||
statusEl.textContent = "";
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
statusEl.className = "error";
|
||||
statusEl.textContent = "Impossible de lire ce PDF. Vérifiez qu'il s'agit bien d'un export du TP.";
|
||||
}
|
||||
}
|
||||
|
||||
function resetAll() {
|
||||
document.getElementById("result").style.display = "none";
|
||||
document.getElementById("dropzone").style.display = "block";
|
||||
document.getElementById("participantsBanner").style.display = "none";
|
||||
document.getElementById("status").textContent = "";
|
||||
document.getElementById("filePicker").value = "";
|
||||
document.getElementById("tp3Table").style.display = "none";
|
||||
}
|
||||
|
||||
const dropzone = document.getElementById("dropzone");
|
||||
dropzone.addEventListener("dragover", e => { e.preventDefault(); dropzone.classList.add("drag"); });
|
||||
dropzone.addEventListener("dragleave", () => dropzone.classList.remove("drag"));
|
||||
dropzone.addEventListener("drop", e => {
|
||||
e.preventDefault();
|
||||
dropzone.classList.remove("drag");
|
||||
const file = e.dataTransfer.files?.[0];
|
||||
if (file) handleFile(file);
|
||||
});
|
||||
document.getElementById("filePicker").addEventListener("change", e => handleFile(e.target.files?.[0]));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1204
exercices/corriger-exercice.html
Normal file
1204
exercices/corriger-exercice.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -44,15 +44,15 @@
|
||||
@keyframes matchSuccess {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
filter: drop-shadow(0 0 0px rgba(76, 175, 80, 0.6));
|
||||
filter: drop-shadow(0 0 0px rgba(29, 158, 117, 0.6));
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.15) rotate(5deg);
|
||||
filter: drop-shadow(0 0 12px rgba(76, 175, 80, 0.8));
|
||||
filter: drop-shadow(0 0 12px rgba(29, 158, 117, 0.8));
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
filter: drop-shadow(0 0 0px rgba(76, 175, 80, 0));
|
||||
filter: drop-shadow(0 0 0px rgba(29, 158, 117, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,14 +101,14 @@
|
||||
/* Pulse Progress Bar */
|
||||
@keyframes progressPulse {
|
||||
0%, 100% {
|
||||
box-shadow: 0 0 8px rgba(29, 158, 117, 0.4);
|
||||
box-shadow: 0 0 8px rgba(186, 117, 23, 0.4);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 24px rgba(29, 158, 117, 0.8);
|
||||
box-shadow: 0 0 24px rgba(186, 117, 23, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
.progress-bar.pulse {
|
||||
.game-progress-fill.pulse {
|
||||
animation: progressPulse 0.6s ease-out;
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
@keyframes statUpdate {
|
||||
0% {
|
||||
transform: scale(0.8);
|
||||
background: rgba(29, 158, 117, 0.2);
|
||||
background: rgba(186, 117, 23, 0.2);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
@@ -255,10 +255,10 @@
|
||||
/* Card glow hover */
|
||||
@keyframes glowCard {
|
||||
0% {
|
||||
box-shadow: 0 0 0px rgba(29, 158, 117, 0);
|
||||
box-shadow: 0 0 0px rgba(186, 117, 23, 0);
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 16px rgba(29, 158, 117, 0.3);
|
||||
box-shadow: 0 0 16px rgba(186, 117, 23, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,10 +281,10 @@
|
||||
/* Pulse button */
|
||||
@keyframes buttonPulse {
|
||||
0%, 100% {
|
||||
box-shadow: 0 0 0px rgba(29, 158, 117, 0.7);
|
||||
box-shadow: 0 0 0px rgba(186, 117, 23, 0.7);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 16px rgba(29, 158, 117, 0.4);
|
||||
box-shadow: 0 0 16px rgba(186, 117, 23, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,15 +7,14 @@
|
||||
============================================ */
|
||||
.game-hud {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
|
||||
grid-template-columns: repeat(4, minmax(120px, 1fr));
|
||||
gap: 16px;
|
||||
margin-bottom: 32px;
|
||||
animation: fadeInUp 0.6s ease-out 0.4s both;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stat-box {
|
||||
background: linear-gradient(135deg, var(--teal-light), var(--white));
|
||||
border: 2px solid var(--teal-mid);
|
||||
background: linear-gradient(135deg, var(--amber-light), var(--white));
|
||||
border: 2px solid var(--amber-mid);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
@@ -38,7 +37,7 @@
|
||||
.stat-box:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
border-color: var(--teal-dark);
|
||||
border-color: var(--amber-dark);
|
||||
}
|
||||
|
||||
.stat-box:hover::before {
|
||||
@@ -57,7 +56,7 @@
|
||||
.stat-box .value {
|
||||
font-size: 32px;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--teal-mid), var(--teal-dark));
|
||||
background: linear-gradient(135deg, var(--amber-mid), var(--amber-dark));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
@@ -73,7 +72,7 @@
|
||||
PROGRESS BAR (Paires trouvées)
|
||||
============================================ */
|
||||
.progress-container {
|
||||
background: var(--teal-light);
|
||||
background: var(--amber-light);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
height: 12px;
|
||||
@@ -82,14 +81,14 @@
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
.game-progress-fill {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, var(--teal-mid), var(--teal-dark));
|
||||
background: linear-gradient(90deg, var(--amber-mid), var(--amber-dark));
|
||||
width: 0%;
|
||||
transition: width 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
}
|
||||
|
||||
.progress-container.pulse .progress-bar {
|
||||
.progress-container.pulse .game-progress-fill {
|
||||
animation: progressPulse 0.6s ease-out;
|
||||
}
|
||||
|
||||
@@ -148,15 +147,15 @@
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background: linear-gradient(135deg, var(--white), var(--teal-light));
|
||||
border-radius: 24px;
|
||||
background: linear-gradient(135deg, var(--white), var(--amber-light));
|
||||
border-radius: 12px;
|
||||
padding: 48px;
|
||||
max-width: 500px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
animation: slideUp 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
border: 2px solid var(--teal-mid);
|
||||
box-shadow: 0 32px 64px rgba(15, 110, 86, 0.3);
|
||||
border: 2px solid var(--amber-mid);
|
||||
box-shadow: 0 32px 64px rgba(186, 117, 23, 0.3);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -177,7 +176,7 @@
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 42px;
|
||||
font-weight: 800;
|
||||
color: var(--teal);
|
||||
color: var(--amber);
|
||||
margin: 32px 0 12px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
@@ -186,7 +185,7 @@
|
||||
.modal-content .score-display {
|
||||
font-size: 64px;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--teal-mid), var(--teal-dark));
|
||||
background: linear-gradient(135deg, var(--amber-mid), var(--amber-dark));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
@@ -203,10 +202,10 @@
|
||||
}
|
||||
|
||||
.stats-summary .stat {
|
||||
background: var(--teal-light);
|
||||
background: var(--amber-light);
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--teal-mid);
|
||||
border: 1px solid var(--amber-mid);
|
||||
animation: popIn 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
}
|
||||
|
||||
@@ -217,7 +216,7 @@
|
||||
|
||||
.stats-summary .stat-value {
|
||||
font-weight: 700;
|
||||
color: var(--teal-dark);
|
||||
color: var(--amber-dark);
|
||||
font-size: 16px;
|
||||
font-family: 'Syne', sans-serif;
|
||||
}
|
||||
@@ -230,6 +229,41 @@
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
PLAYER NAME MODAL
|
||||
============================================ */
|
||||
.name-modal-content h2 {
|
||||
margin-top: 32px;
|
||||
}
|
||||
|
||||
.name-modal-text {
|
||||
color: var(--text-muted);
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 24px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.name-input {
|
||||
width: 100%;
|
||||
padding: 14px 16px;
|
||||
font-size: 16px;
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
border: 2px solid var(--amber-mid);
|
||||
border-radius: 8px;
|
||||
background: var(--white);
|
||||
color: var(--text);
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.name-input:focus {
|
||||
outline: none;
|
||||
border-color: var(--amber-dark);
|
||||
box-shadow: 0 0 0 3px rgba(186, 117, 23, 0.15);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
ACHIEVEMENTS
|
||||
============================================ */
|
||||
@@ -289,52 +323,6 @@
|
||||
min-width: 140px;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
PAUSE MODAL
|
||||
============================================ */
|
||||
.pause-modal {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1999;
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
.pause-content {
|
||||
background: var(--white);
|
||||
border-radius: 16px;
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
border: 2px solid var(--teal-mid);
|
||||
animation: slideUp 0.4s ease-out;
|
||||
}
|
||||
|
||||
.pause-content h2 {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 32px;
|
||||
color: var(--teal);
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.pause-content .pause-timer {
|
||||
font-size: 48px;
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-weight: 800;
|
||||
color: var(--teal-dark);
|
||||
margin-bottom: 24px;
|
||||
animation: timerTick 0.5s ease-out;
|
||||
}
|
||||
|
||||
.pause-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
RESPONSIVE DESIGN
|
||||
============================================ */
|
||||
|
||||
@@ -2,18 +2,25 @@
|
||||
LEADERBOARD & PLAYER STATS
|
||||
============================================ */
|
||||
|
||||
.leaderboard-section {
|
||||
margin-top: 80px;
|
||||
.leaderboard-panel {
|
||||
animation: fadeInUp 0.6s ease-out 0.6s both;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stats-panel {
|
||||
animation: fadeInUp 0.6s ease-out 0.6s both;
|
||||
}
|
||||
|
||||
.leaderboard-section h2 {
|
||||
.leaderboard-panel h2 {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: clamp(24px, 5vw, 32px);
|
||||
font-size: clamp(20px, 4vw, 26px);
|
||||
font-weight: 800;
|
||||
color: var(--teal);
|
||||
margin-bottom: 24px;
|
||||
text-align: center;
|
||||
letter-spacing: -0.5px;
|
||||
color: var(--text);
|
||||
margin: 0 auto 24px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 3px solid var(--amber-mid);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
@@ -30,7 +37,7 @@
|
||||
.tab-btn {
|
||||
padding: 10px 20px;
|
||||
background: var(--white);
|
||||
border: 2px solid var(--teal-light);
|
||||
border: 2px solid var(--amber-light);
|
||||
border-radius: 8px;
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 12px;
|
||||
@@ -43,13 +50,13 @@
|
||||
}
|
||||
|
||||
.tab-btn:hover {
|
||||
border-color: var(--teal-mid);
|
||||
color: var(--teal-mid);
|
||||
border-color: var(--amber-mid);
|
||||
color: var(--amber-mid);
|
||||
}
|
||||
|
||||
.tab-btn.active {
|
||||
background: linear-gradient(135deg, var(--teal-mid), var(--teal-dark));
|
||||
border-color: var(--teal-dark);
|
||||
background: linear-gradient(135deg, var(--amber-mid), var(--amber-dark));
|
||||
border-color: var(--amber-dark);
|
||||
color: var(--white);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
@@ -58,12 +65,13 @@
|
||||
LEADERBOARD LIST
|
||||
============================================ */
|
||||
.leaderboard {
|
||||
background: linear-gradient(135deg, var(--teal-light), var(--white));
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(135deg, var(--amber-light), var(--white));
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
border: 2px solid var(--teal-mid);
|
||||
border: 2px solid var(--amber-mid);
|
||||
margin-bottom: 48px;
|
||||
box-shadow: var(--shadow-sm);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.leaderboard-list {
|
||||
@@ -73,19 +81,25 @@
|
||||
}
|
||||
|
||||
.rank-item {
|
||||
display: grid;
|
||||
grid-template-columns: 50px 1fr auto auto;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
background: var(--white);
|
||||
padding: 16px;
|
||||
padding: 14px;
|
||||
border-radius: 8px;
|
||||
transition: all 0.3s ease;
|
||||
border-left: 4px solid var(--teal-light);
|
||||
border-left: 4px solid var(--amber-light);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.rank-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.rank-item::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
@@ -93,14 +107,14 @@
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(29, 158, 117, 0.1), transparent);
|
||||
background: linear-gradient(90deg, transparent, rgba(186, 117, 23, 0.1), transparent);
|
||||
transition: left 0.5s ease;
|
||||
}
|
||||
|
||||
.rank-item:hover {
|
||||
transform: translateX(8px);
|
||||
box-shadow: 0 4px 12px rgba(15, 110, 86, 0.15);
|
||||
border-left-color: var(--teal-mid);
|
||||
box-shadow: 0 4px 12px rgba(186, 117, 23, 0.15);
|
||||
border-left-color: var(--amber-mid);
|
||||
}
|
||||
|
||||
.rank-item:hover::before {
|
||||
@@ -111,35 +125,21 @@
|
||||
.rank-number {
|
||||
font-weight: 800;
|
||||
font-size: 18px;
|
||||
color: var(--teal-mid);
|
||||
color: var(--amber-mid);
|
||||
text-align: center;
|
||||
font-family: 'Syne', sans-serif;
|
||||
}
|
||||
|
||||
.rank-number.medal-1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.rank-number.medal-1::before {
|
||||
content: '🥇';
|
||||
display: block;
|
||||
}
|
||||
|
||||
.rank-number.medal-2::before {
|
||||
content: '🥈';
|
||||
display: block;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.rank-number.medal-3::before {
|
||||
content: '🥉';
|
||||
display: block;
|
||||
font-size: 20px;
|
||||
.rank-number.medal-1,
|
||||
.rank-number.medal-2,
|
||||
.rank-number.medal-3 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
/* Infos joueur */
|
||||
.rank-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.player-name {
|
||||
@@ -147,17 +147,20 @@
|
||||
color: var(--text);
|
||||
margin-bottom: 4px;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.player-stats {
|
||||
font-size: 12px;
|
||||
.rank-meta {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.player-stats span {
|
||||
.rank-meta span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
@@ -166,39 +169,11 @@
|
||||
/* Score et difficulté */
|
||||
.rank-score {
|
||||
font-weight: 700;
|
||||
color: var(--teal-dark);
|
||||
font-size: 18px;
|
||||
color: var(--amber-dark);
|
||||
font-size: 16px;
|
||||
font-family: 'Syne', sans-serif;
|
||||
min-width: 60px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.rank-difficulty {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
background: var(--teal-light);
|
||||
color: var(--teal-dark);
|
||||
min-width: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.rank-difficulty.easy {
|
||||
background: #C8E6C9;
|
||||
color: #2E7D32;
|
||||
}
|
||||
|
||||
.rank-difficulty.normal {
|
||||
background: var(--teal-light);
|
||||
color: var(--teal-dark);
|
||||
}
|
||||
|
||||
.rank-difficulty.hard {
|
||||
background: #FFCCBC;
|
||||
color: #D84315;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Message si pas de scores */
|
||||
@@ -227,32 +202,32 @@
|
||||
PLAYER STATS SECTION
|
||||
============================================ */
|
||||
.player-stats {
|
||||
background: linear-gradient(135deg, rgba(15, 110, 86, 0.05), transparent);
|
||||
border-radius: 16px;
|
||||
padding: 32px;
|
||||
border: 2px solid var(--teal-light);
|
||||
background: linear-gradient(135deg, rgba(186, 117, 23, 0.05), transparent);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
border: 2px solid var(--amber-light);
|
||||
}
|
||||
|
||||
.player-stats h3 {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 24px;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: var(--teal);
|
||||
margin-bottom: 24px;
|
||||
color: var(--amber);
|
||||
margin-bottom: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
gap: 16px;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: var(--white);
|
||||
border: 2px solid var(--teal-light);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
border: 2px solid var(--amber-light);
|
||||
border-radius: 10px;
|
||||
padding: 14px 8px;
|
||||
text-align: center;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
@@ -263,27 +238,27 @@
|
||||
.stat-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: var(--shadow-md);
|
||||
border-color: var(--teal-mid);
|
||||
border-color: var(--amber-mid);
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
font-size: 32px;
|
||||
margin-bottom: 12px;
|
||||
font-size: 22px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 11px;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 28px;
|
||||
font-size: 20px;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--teal-mid), var(--teal-dark));
|
||||
background: linear-gradient(135deg, var(--amber-mid), var(--amber-dark));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
@@ -291,7 +266,7 @@
|
||||
}
|
||||
|
||||
.stat-card.high-value .stat-value {
|
||||
font-size: 32px;
|
||||
font-size: 22px;
|
||||
animation: popIn 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
}
|
||||
|
||||
@@ -324,28 +299,19 @@
|
||||
RESPONSIVE DESIGN
|
||||
============================================ */
|
||||
@media (max-width: 768px) {
|
||||
.leaderboard-section h2 {
|
||||
.leaderboard-panel h2 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
.tabs {
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
|
||||
.tab-btn {
|
||||
padding: 8px 16px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.rank-item {
|
||||
grid-template-columns: 40px 1fr auto;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.rank-difficulty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.rank-number {
|
||||
font-size: 16px;
|
||||
}
|
||||
@@ -355,29 +321,29 @@
|
||||
}
|
||||
|
||||
.player-stats {
|
||||
padding: 24px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
|
||||
.player-stats h3 {
|
||||
font-size: 20px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
|
||||
.stats-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
|
||||
.stat-card {
|
||||
padding: 16px;
|
||||
padding: 14px 10px;
|
||||
}
|
||||
|
||||
|
||||
.stat-icon {
|
||||
font-size: 28px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,17 +363,10 @@
|
||||
}
|
||||
|
||||
.rank-item {
|
||||
grid-template-columns: 40px 1fr;
|
||||
gap: 10px;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.rank-score {
|
||||
grid-column: 1 / -1;
|
||||
text-align: left;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
|
||||
.rank-number {
|
||||
font-size: 14px;
|
||||
}
|
||||
@@ -419,24 +378,25 @@
|
||||
.player-stats {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
|
||||
.player-stats h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
padding: 12px 8px;
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
|
||||
:root {
|
||||
/* Gamification Colors */
|
||||
--success: #4CAF50;
|
||||
--success: var(--teal-mid);
|
||||
--warning: #FF9800;
|
||||
--info: #2196F3;
|
||||
--accent: #FFD700;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 4px 8px rgba(15, 110, 86, 0.1);
|
||||
--shadow-md: 0 8px 16px rgba(15, 110, 86, 0.15);
|
||||
--shadow-lg: 0 16px 32px rgba(15, 110, 86, 0.25);
|
||||
/* Shadows (alignées sur le langage visuel du site) */
|
||||
--shadow-sm: 0 4px 12px rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 12px 32px rgba(0, 0, 0, 0.1);
|
||||
--shadow-lg: 0 20px 50px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
@@ -21,12 +21,12 @@
|
||||
============================================ */
|
||||
main {
|
||||
margin-top: 70px;
|
||||
padding: 40px;
|
||||
padding: 96px 40px 40px;
|
||||
min-height: calc(100vh - 70px);
|
||||
}
|
||||
|
||||
.game-container {
|
||||
max-width: 1200px;
|
||||
max-width: 1440px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@@ -34,15 +34,16 @@ main {
|
||||
INTRO SECTION
|
||||
============================================ */
|
||||
.intro-section {
|
||||
margin-bottom: 60px;
|
||||
animation: fadeInDown 0.6s ease-out;
|
||||
margin-bottom: 48px;
|
||||
animation: fadeIn 0.6s ease-out;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.intro-section h1 {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: clamp(28px, 5vw, 48px);
|
||||
font-size: clamp(28px, 5vw, 44px);
|
||||
font-weight: 800;
|
||||
color: var(--teal);
|
||||
color: var(--amber);
|
||||
margin-bottom: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -56,11 +57,10 @@ main {
|
||||
}
|
||||
|
||||
.intro-box {
|
||||
background: linear-gradient(135deg, var(--teal-light), var(--white));
|
||||
border-left: 4px solid var(--teal-mid);
|
||||
background: linear-gradient(135deg, var(--amber-light), var(--white));
|
||||
border-left: 4px solid var(--amber-mid);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-bottom: 32px;
|
||||
font-size: 0.95em;
|
||||
color: var(--text-muted);
|
||||
line-height: 1.6;
|
||||
@@ -70,93 +70,148 @@ main {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
TOP BAR (niveau + stats en temps réel)
|
||||
============================================ */
|
||||
.game-top-bar {
|
||||
max-width: 1440px;
|
||||
margin: 0 auto 32px;
|
||||
background: var(--white);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 24px clamp(20px, 3vw, 36px);
|
||||
box-shadow: var(--shadow-sm);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: clamp(20px, 3vw, 40px);
|
||||
animation: fadeInUp 0.6s ease-out 0.2s both;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
GAME LAYOUT (classement / jeu / stats)
|
||||
============================================ */
|
||||
.game-layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 320px) minmax(0, 760px) minmax(0, 320px);
|
||||
grid-template-areas: "leaderboard game stats";
|
||||
justify-content: center;
|
||||
align-items: start;
|
||||
gap: 32px;
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
|
||||
.leaderboard-panel {
|
||||
grid-area: leaderboard;
|
||||
}
|
||||
|
||||
.stats-panel {
|
||||
grid-area: stats;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
GAME SECTION / PANEL
|
||||
============================================ */
|
||||
.game-section {
|
||||
grid-area: game;
|
||||
animation: fadeInUp 0.6s ease-out 0.3s both;
|
||||
}
|
||||
|
||||
.game-panel {
|
||||
background: var(--white);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: clamp(20px, 4vw, 32px);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
DIFFICULTY SELECTOR
|
||||
============================================ */
|
||||
.difficulty-selector {
|
||||
margin-bottom: 48px;
|
||||
text-align: center;
|
||||
animation: fadeInUp 0.6s ease-out 0.2s both;
|
||||
text-align: left;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.difficulty-selector label {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
||||
grid-template-columns: repeat(3, minmax(100px, 1fr));
|
||||
gap: 12px;
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.btn-difficulty {
|
||||
background: var(--white);
|
||||
border: 2px solid var(--teal-light);
|
||||
border-radius: 8px;
|
||||
padding: 16px 12px;
|
||||
background: var(--amber-light);
|
||||
background: linear-gradient(135deg, rgba(250, 238, 218, 0.5), transparent);
|
||||
border: 2px solid transparent;
|
||||
border-radius: 12px;
|
||||
padding: 14px 12px;
|
||||
font-family: 'Syne', sans-serif;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.btn-difficulty:hover {
|
||||
border-color: var(--teal-mid);
|
||||
transform: translateY(-4px);
|
||||
border-color: var(--amber-mid);
|
||||
transform: translateY(-3px);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.btn-difficulty.active {
|
||||
background: linear-gradient(135deg, var(--teal-light), var(--white));
|
||||
border-color: var(--teal-mid);
|
||||
color: var(--teal);
|
||||
background: linear-gradient(135deg, var(--amber-mid), var(--amber-dark));
|
||||
border-color: var(--amber-dark);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.btn-difficulty.active .btn-label,
|
||||
.btn-difficulty.active .btn-desc {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
font-size: 20px;
|
||||
line-height: 1;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.btn-label {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: var(--teal);
|
||||
color: var(--amber);
|
||||
}
|
||||
|
||||
.btn-desc {
|
||||
font-size: 12px;
|
||||
font-size: 11px;
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
color: var(--text-muted);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
GAME SECTION
|
||||
============================================ */
|
||||
.game-section {
|
||||
margin-bottom: 80px;
|
||||
animation: fadeInUp 0.6s ease-out 0.3s both;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
GAME GRID & CARDS
|
||||
============================================ */
|
||||
.game-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(clamp(70px, 15vw, 140px), 1fr));
|
||||
gap: clamp(12px, 2vw, 20px);
|
||||
max-width: 900px;
|
||||
margin: 0 auto 40px;
|
||||
grid-template-columns: repeat(auto-fit, minmax(clamp(70px, 15vw, 110px), 1fr));
|
||||
gap: clamp(10px, 2vw, 16px);
|
||||
margin: 0 auto 32px;
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, rgba(225, 245, 238, 0.4), transparent);
|
||||
border-radius: 16px;
|
||||
border: 1px solid var(--teal-light);
|
||||
background: linear-gradient(135deg, rgba(250, 238, 218, 0.4), transparent);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--amber-light);
|
||||
}
|
||||
|
||||
/* MEMORY CARD STYLES */
|
||||
@@ -188,16 +243,19 @@ main {
|
||||
}
|
||||
|
||||
.card-face.front {
|
||||
background: linear-gradient(135deg, var(--teal-light), var(--teal-light));
|
||||
border: 2px solid var(--teal-mid);
|
||||
color: var(--teal-dark);
|
||||
background:
|
||||
radial-gradient(circle at 30% 25%, rgba(255, 255, 255, 0.6), transparent 60%),
|
||||
linear-gradient(135deg, var(--amber-mid), var(--amber-dark));
|
||||
border: 2px solid var(--amber-dark);
|
||||
color: var(--white);
|
||||
box-shadow: var(--shadow-sm);
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.card-face.back {
|
||||
transform: rotateY(180deg);
|
||||
background: linear-gradient(135deg, var(--white), var(--teal-light));
|
||||
border: 2px solid var(--teal-mid);
|
||||
background: linear-gradient(135deg, var(--white), var(--amber-light));
|
||||
border: 2px solid var(--amber-mid);
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 8px;
|
||||
@@ -246,7 +304,7 @@ main {
|
||||
}
|
||||
|
||||
.memory-card.matched .card-face.back {
|
||||
background: linear-gradient(135deg, var(--white), rgba(76, 175, 80, 0.2));
|
||||
background: linear-gradient(135deg, var(--white), rgba(29, 158, 117, 0.2));
|
||||
border-color: var(--success);
|
||||
}
|
||||
|
||||
@@ -271,26 +329,16 @@ footer {
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
BUTTONS
|
||||
BUTTONS (métriques héritées du style général du site)
|
||||
============================================ */
|
||||
.btn {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
padding: 12px 24px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, var(--teal-mid), var(--teal-dark));
|
||||
background: linear-gradient(135deg, var(--amber-mid), var(--amber-dark));
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
@@ -301,27 +349,55 @@ footer {
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--white);
|
||||
border: 2px solid var(--teal-mid);
|
||||
color: var(--teal-mid);
|
||||
border: 2px solid var(--amber-mid);
|
||||
color: var(--amber-mid);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: var(--teal-light);
|
||||
border-color: var(--teal-dark);
|
||||
background: var(--amber-light);
|
||||
border-color: var(--amber-dark);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
RESPONSIVE DESIGN
|
||||
============================================ */
|
||||
@media (max-width: 1100px) {
|
||||
.game-layout {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
"game"
|
||||
"leaderboard"
|
||||
"stats";
|
||||
gap: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.game-top-bar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.difficulty-selector {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
max-width: 520px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
main {
|
||||
padding: 20px;
|
||||
padding: 56px 20px 20px;
|
||||
}
|
||||
|
||||
|
||||
.intro-section h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
|
||||
.game-grid {
|
||||
gap: 12px;
|
||||
padding: 16px;
|
||||
@@ -345,9 +421,9 @@ footer {
|
||||
|
||||
@media (max-width: 480px) {
|
||||
main {
|
||||
padding: 16px;
|
||||
padding: 40px 16px 16px;
|
||||
}
|
||||
|
||||
|
||||
.intro-section h1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
@@ -175,7 +175,6 @@ class GameSessionState {
|
||||
this.moves = 0;
|
||||
this.score = 0;
|
||||
this.matched = 0;
|
||||
this.isPaused = false;
|
||||
this.gameActive = false;
|
||||
}
|
||||
|
||||
@@ -190,7 +189,6 @@ class GameSessionState {
|
||||
this.score = 0;
|
||||
this.matched = 0;
|
||||
this.gameActive = true;
|
||||
this.isPaused = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -192,17 +192,18 @@ class LeaderboardManager {
|
||||
const medal = index < 3 ? `class="rank-number medal-${index + 1}"` : 'class="rank-number"';
|
||||
|
||||
rankItem.innerHTML = `
|
||||
<div ${medal}>${rankNumber}</div>
|
||||
<div class="rank-top">
|
||||
<div ${medal}>${rankNumber}</div>
|
||||
<div class="rank-score">${formatNumber(score.score)}</div>
|
||||
</div>
|
||||
<div class="rank-info">
|
||||
<div class="player-name">${this.escapeHTML(score.playerName)}</div>
|
||||
<div class="player-stats">
|
||||
<div class="rank-meta">
|
||||
<span>⏱ ${formatTime(score.timeSeconds)}</span>
|
||||
<span>🎯 ${score.moves} mouvements</span>
|
||||
${score.isPerfect ? '<span>✨ Parfait</span>' : ''}
|
||||
<span>🎯 ${score.moves}</span>
|
||||
${score.isPerfect ? '<span>✨</span>' : ''}
|
||||
</div>
|
||||
</div>
|
||||
<div class="rank-score">${formatNumber(score.score)}</div>
|
||||
<div class="rank-difficulty ${score.difficulty}">${DIFFICULTY_MODES[score.difficulty].name}</div>
|
||||
`;
|
||||
|
||||
leaderboardList.appendChild(rankItem);
|
||||
|
||||
@@ -14,7 +14,6 @@ class MemoryGameEngine {
|
||||
moves: 0,
|
||||
score: 0,
|
||||
isProcessing: false,
|
||||
isPaused: false,
|
||||
gameStarted: false
|
||||
};
|
||||
this.startTime = null;
|
||||
@@ -128,8 +127,7 @@ class MemoryGameEngine {
|
||||
if (this.gameState.flipped.length === 2) return;
|
||||
if (this.cards[cardIndex].isMatched) return;
|
||||
if (this.gameState.flipped.includes(cardIndex)) return;
|
||||
if (this.gameState.isPaused) return;
|
||||
|
||||
|
||||
// Retourner la carte
|
||||
this.flipCard(cardIndex);
|
||||
this.gameState.flipped.push(cardIndex);
|
||||
@@ -260,9 +258,7 @@ class MemoryGameEngine {
|
||||
this.startTime = Date.now();
|
||||
|
||||
this.timerInterval = setInterval(() => {
|
||||
if (!this.gameState.isPaused) {
|
||||
this.updateTimer();
|
||||
}
|
||||
this.updateTimer();
|
||||
}, 100);
|
||||
|
||||
this.analytics.trackGameStart(this.difficulty);
|
||||
@@ -429,7 +425,6 @@ class MemoryGameEngine {
|
||||
moves: 0,
|
||||
score: 0,
|
||||
isProcessing: false,
|
||||
isPaused: false,
|
||||
gameStarted: false
|
||||
};
|
||||
|
||||
@@ -444,34 +439,13 @@ class MemoryGameEngine {
|
||||
document.getElementById('timer-display').style.animation = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause/Reprise
|
||||
*/
|
||||
togglePause() {
|
||||
if (!this.gameState.gameStarted) return;
|
||||
|
||||
this.gameState.isPaused = !this.gameState.isPaused;
|
||||
const pauseBtn = document.getElementById('pause-btn');
|
||||
|
||||
if (this.gameState.isPaused) {
|
||||
pauseBtn.textContent = '▶ Reprendre';
|
||||
pauseBtn.classList.add('paused');
|
||||
} else {
|
||||
pauseBtn.textContent = '⏸ Pause';
|
||||
pauseBtn.classList.remove('paused');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup event listeners
|
||||
*/
|
||||
setupEventListeners() {
|
||||
// Bouton restart
|
||||
document.getElementById('restart-btn').addEventListener('click', () => this.restart());
|
||||
|
||||
// Bouton pause
|
||||
document.getElementById('pause-btn').addEventListener('click', () => this.togglePause());
|
||||
|
||||
|
||||
// Sélecteur de difficulté
|
||||
document.querySelectorAll('.btn-difficulty').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
@@ -512,14 +486,51 @@ class MemoryGameEngine {
|
||||
// ============================================
|
||||
let game;
|
||||
|
||||
/**
|
||||
* Demander le nom du joueur à la première partie
|
||||
*/
|
||||
function setupPlayerNameModal(onReady) {
|
||||
const nameConfirmed = localStorage.getItem('nextgn_name_confirmed') === 'true';
|
||||
|
||||
if (nameConfirmed) {
|
||||
onReady();
|
||||
return;
|
||||
}
|
||||
|
||||
const modal = document.getElementById('player-name-modal');
|
||||
const input = document.getElementById('player-name-input');
|
||||
const confirmBtn = document.getElementById('player-name-confirm');
|
||||
|
||||
modal.classList.remove('hidden');
|
||||
input.focus();
|
||||
|
||||
const confirmName = () => {
|
||||
const name = input.value.trim();
|
||||
localStorage.setItem('nextgn_playerName', name || getPlayerName());
|
||||
localStorage.setItem('nextgn_name_confirmed', 'true');
|
||||
modal.classList.add('hidden');
|
||||
onReady();
|
||||
};
|
||||
|
||||
confirmBtn.addEventListener('click', confirmName, { once: true });
|
||||
input.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter') confirmName();
|
||||
}, { once: true });
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// Initialiser le jeu
|
||||
game = new MemoryGameEngine('normal');
|
||||
|
||||
// Afficher le leaderboard initial
|
||||
LeaderboardManager.updateDisplay('all');
|
||||
LeaderboardManager.updatePlayerStats();
|
||||
|
||||
|
||||
setupPlayerNameModal(() => {
|
||||
LeaderboardManager.updateDisplay('all');
|
||||
LeaderboardManager.updatePlayerStats();
|
||||
});
|
||||
|
||||
// Initialiser le jeu
|
||||
game = new MemoryGameEngine('normal');
|
||||
|
||||
// Scroll progress
|
||||
window.addEventListener('scroll', () => {
|
||||
game.updateHUD();
|
||||
|
||||
@@ -9,7 +9,7 @@ const PICTOGRAMMES = [
|
||||
{
|
||||
id: 1,
|
||||
nom: "Gaz comprimé",
|
||||
filename: "1-gaz-comprime.png",
|
||||
filename: "sous_pression.jpg",
|
||||
texte: "Je suis sous pression",
|
||||
danger: "Danger physique",
|
||||
couleur: "teal"
|
||||
@@ -17,15 +17,15 @@ const PICTOGRAMMES = [
|
||||
{
|
||||
id: 2,
|
||||
nom: "Exclamation",
|
||||
filename: "2-exclamation.png",
|
||||
texte: "Je nuis gravement à la santé",
|
||||
danger: "Danger pour la santé",
|
||||
filename: "nocif_irritant_ozone.jpg",
|
||||
texte: "J'altère la santé ou la couche d'ozone",
|
||||
danger: "Danger pour la santé/Environnement",
|
||||
couleur: "teal"
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
nom: "Explosion",
|
||||
filename: "3-explosion.png",
|
||||
filename: "explosif.jpg",
|
||||
texte: "J'explose",
|
||||
danger: "Danger physique",
|
||||
couleur: "teal"
|
||||
@@ -33,7 +33,7 @@ const PICTOGRAMMES = [
|
||||
{
|
||||
id: 4,
|
||||
nom: "Crâne",
|
||||
filename: "4-crane.png",
|
||||
filename: "toxicite_aigue.jpg",
|
||||
texte: "Je tue",
|
||||
danger: "Danger physique",
|
||||
couleur: "teal"
|
||||
@@ -41,7 +41,7 @@ const PICTOGRAMMES = [
|
||||
{
|
||||
id: 5,
|
||||
nom: "Flamme",
|
||||
filename: "5-flamme.png",
|
||||
filename: "inflammable.jpg",
|
||||
texte: "Je flambe",
|
||||
danger: "Danger physique",
|
||||
couleur: "teal"
|
||||
@@ -49,7 +49,7 @@ const PICTOGRAMMES = [
|
||||
{
|
||||
id: 6,
|
||||
nom: "Comburant",
|
||||
filename: "6-comburant.png",
|
||||
filename: "comburant.jpg",
|
||||
texte: "Je fais flamber",
|
||||
danger: "Danger physique",
|
||||
couleur: "teal"
|
||||
@@ -57,7 +57,7 @@ const PICTOGRAMMES = [
|
||||
{
|
||||
id: 7,
|
||||
nom: "Environnement",
|
||||
filename: "7-environnement.png",
|
||||
filename: "pollution.jpg",
|
||||
texte: "Je pollue",
|
||||
danger: "Danger pour l'environnement",
|
||||
couleur: "teal"
|
||||
@@ -65,17 +65,17 @@ const PICTOGRAMMES = [
|
||||
{
|
||||
id: 8,
|
||||
nom: "Corrosion",
|
||||
filename: "8-corrosion.png",
|
||||
filename: "corrosif.jpg",
|
||||
texte: "Je ronge",
|
||||
danger: "Danger physique",
|
||||
couleur: "teal"
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
nom: "Santé/Environnement",
|
||||
filename: "9-sante-environnement.png",
|
||||
texte: "J'altère la santé ou la couche d'ozone",
|
||||
danger: "Danger pour la santé/Environnement",
|
||||
nom: "Santé (CMR)",
|
||||
filename: "cmr.jpg",
|
||||
texte: "Je nuis gravement à la santé",
|
||||
danger: "Danger pour la santé",
|
||||
couleur: "teal"
|
||||
}
|
||||
];
|
||||
|
||||
@@ -3,20 +3,20 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Memory Pictogrammes GHS - NextGN Formation</title>
|
||||
<title>Memory Pictogrammes GHS - Gauthier Chombart & Nathan Chauwin</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=DM+Sans:ital,wght@0,300;0,400;0,500;1,300&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Styles -->
|
||||
<link rel="stylesheet" href="../../header-style.css"/>
|
||||
<link rel="stylesheet" href="assets/css/memory-game.css">
|
||||
<link rel="stylesheet" href="assets/css/hud.css">
|
||||
<link rel="stylesheet" href="assets/css/animations.css">
|
||||
<link rel="stylesheet" href="assets/css/leaderboard.css">
|
||||
<link rel="stylesheet" href="assets/css/memory-game.css?v=3">
|
||||
<link rel="stylesheet" href="assets/css/hud.css?v=3">
|
||||
<link rel="stylesheet" href="assets/css/animations.css?v=3">
|
||||
<link rel="stylesheet" href="assets/css/leaderboard.css?v=3">
|
||||
</head>
|
||||
<body>
|
||||
<!-- HEADER NextGN Formation -->
|
||||
<!-- HEADER Gauthier Chombart & Nathan Chauwin -->
|
||||
<header>
|
||||
<div class="logo">NextGN Formation</div>
|
||||
<div class="logo">Gauthier Chombart & Nathan Chauwin</div>
|
||||
<nav>
|
||||
<a href="../../index.html">Accueil</a>
|
||||
<a href="../../index.html#formations">Exercices</a>
|
||||
@@ -36,125 +36,158 @@
|
||||
<main class="game-container">
|
||||
<!-- INTRO SECTION -->
|
||||
<section class="intro-section">
|
||||
<h1>🎮 Memory Pictogrammes GHS</h1>
|
||||
<h1>Memory pictogrammes</h1>
|
||||
<p class="subtitle">Maîtrisez les 9 symboles de danger</p>
|
||||
|
||||
|
||||
<div class="intro-box">
|
||||
<p>
|
||||
<strong>Objectif :</strong> Retrouvez les paires en associant chaque pictogramme à sa signification.
|
||||
Plus rapide vous êtes, plus de points vous gagnez! 🏆
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- TOP BAR (niveau + stats en temps réel) -->
|
||||
<div class="game-top-bar">
|
||||
<!-- DIFFICULTY SELECTOR -->
|
||||
<div class="difficulty-selector">
|
||||
<label>Choisir le niveau :</label>
|
||||
<label>Choisir le niveau</label>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-difficulty" data-difficulty="easy">
|
||||
<span class="btn-icon">🌱</span>
|
||||
<span class="btn-label">Facile</span>
|
||||
<span class="btn-desc">4 paires</span>
|
||||
</button>
|
||||
<button class="btn btn-difficulty active" data-difficulty="normal">
|
||||
<span class="btn-icon">🎯</span>
|
||||
<span class="btn-label">Normal</span>
|
||||
<span class="btn-desc">9 paires</span>
|
||||
</button>
|
||||
<button class="btn btn-difficulty" data-difficulty="hard">
|
||||
<span class="btn-icon">🔥</span>
|
||||
<span class="btn-label">Difficile</span>
|
||||
<span class="btn-desc">2 min chrono</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- GAME SECTION -->
|
||||
<section class="game-section">
|
||||
<!-- HUD (Stats en temps réel) -->
|
||||
<div class="game-hud">
|
||||
<div class="stat-box">
|
||||
<div class="label">Score</div>
|
||||
<div class="label">🏆 Score</div>
|
||||
<div class="value" id="score-display">0</div>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<div class="label">Mouvements</div>
|
||||
<div class="label">👆 Mouvements</div>
|
||||
<div class="value" id="moves-display">0</div>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<div class="label">Temps</div>
|
||||
<div class="label">⏱ Temps</div>
|
||||
<div class="value" id="timer-display">00:00</div>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<div class="label">Paires</div>
|
||||
<div class="label">🧩 Paires</div>
|
||||
<div class="value" id="pairs-display">0/9</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PROGRESS BAR -->
|
||||
<div class="progress-container">
|
||||
<div class="progress-bar" id="progress-bar"></div>
|
||||
</div>
|
||||
<!-- GAME LAYOUT (classement / jeu / statistiques) -->
|
||||
<div class="game-layout">
|
||||
<!-- LEADERBOARD PANEL (gauche) -->
|
||||
<aside class="leaderboard-panel">
|
||||
<h2>🏆 Classement</h2>
|
||||
|
||||
<!-- GAME GRID -->
|
||||
<div class="game-grid" id="game-grid">
|
||||
<!-- Cartes générées par JS -->
|
||||
</div>
|
||||
|
||||
<!-- CONTROLS -->
|
||||
<div class="game-controls">
|
||||
<button class="btn btn-primary" id="restart-btn">
|
||||
🔄 Recommencer
|
||||
</button>
|
||||
<button class="btn btn-secondary" id="pause-btn">
|
||||
⏸ Pause
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- LEADERBOARD SECTION -->
|
||||
<section class="leaderboard-section">
|
||||
<h2>🏆 Classement</h2>
|
||||
|
||||
<div class="tabs">
|
||||
<button class="tab-btn active" data-filter="all">Tous</button>
|
||||
<button class="tab-btn" data-filter="easy">Facile</button>
|
||||
<button class="tab-btn" data-filter="normal">Normal</button>
|
||||
<button class="tab-btn" data-filter="hard">Difficile</button>
|
||||
</div>
|
||||
|
||||
<div class="leaderboard">
|
||||
<div class="leaderboard-list" id="leaderboard-list">
|
||||
<!-- Rempli par JS -->
|
||||
<div class="tabs">
|
||||
<button class="tab-btn active" data-filter="all">Tous</button>
|
||||
<button class="tab-btn" data-filter="easy">Facile</button>
|
||||
<button class="tab-btn" data-filter="normal">Normal</button>
|
||||
<button class="tab-btn" data-filter="hard">Difficile</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PLAYER STATS -->
|
||||
<div class="player-stats">
|
||||
<h3>Vos statistiques</h3>
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon">🎮</div>
|
||||
<div class="stat-label">Jeux joués</div>
|
||||
<div class="stat-value" id="total-games">0</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon">⭐</div>
|
||||
<div class="stat-label">Meilleur score</div>
|
||||
<div class="stat-value" id="best-score">0</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon">⚡</div>
|
||||
<div class="stat-label">Temps record</div>
|
||||
<div class="stat-value" id="best-time">--</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon">🏅</div>
|
||||
<div class="stat-label">Taux de réussite</div>
|
||||
<div class="stat-value" id="win-rate">0%</div>
|
||||
<div class="leaderboard">
|
||||
<div class="leaderboard-list" id="leaderboard-list">
|
||||
<!-- Rempli par JS -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</aside>
|
||||
|
||||
<!-- GAME SECTION (centre) -->
|
||||
<section class="game-section">
|
||||
<div class="game-panel">
|
||||
<!-- PROGRESS BAR -->
|
||||
<div class="progress-container">
|
||||
<div class="game-progress-fill" id="progress-bar"></div>
|
||||
</div>
|
||||
|
||||
<!-- GAME GRID -->
|
||||
<div class="game-grid" id="game-grid">
|
||||
<!-- Cartes générées par JS -->
|
||||
</div>
|
||||
|
||||
<!-- CONTROLS -->
|
||||
<div class="game-controls">
|
||||
<button class="btn btn-primary" id="restart-btn">
|
||||
🔄 Recommencer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- PLAYER STATS PANEL (droite) -->
|
||||
<aside class="stats-panel">
|
||||
<div class="player-stats">
|
||||
<h3>Vos statistiques</h3>
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon">🎮</div>
|
||||
<div class="stat-label">Jeux joués</div>
|
||||
<div class="stat-value" id="total-games">0</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon">⭐</div>
|
||||
<div class="stat-label">Meilleur score</div>
|
||||
<div class="stat-value" id="best-score">0</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon">⚡</div>
|
||||
<div class="stat-label">Temps record</div>
|
||||
<div class="stat-value" id="best-time">--</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon">🏅</div>
|
||||
<div class="stat-label">Taux de réussite</div>
|
||||
<div class="stat-value" id="win-rate">0%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- PLAYER NAME MODAL (1ère partie) -->
|
||||
<div class="victory-modal hidden" id="player-name-modal">
|
||||
<div class="modal-content name-modal-content">
|
||||
<h2>Bienvenue ! 👋</h2>
|
||||
<p class="name-modal-text">
|
||||
Entrez votre nom ou un pseudo pour apparaître dans le classement général.
|
||||
</p>
|
||||
<input
|
||||
type="text"
|
||||
id="player-name-input"
|
||||
class="name-input"
|
||||
maxlength="20"
|
||||
placeholder="Votre nom ou pseudo"
|
||||
autocomplete="off"
|
||||
>
|
||||
<div class="modal-actions">
|
||||
<button class="btn btn-primary" id="player-name-confirm">
|
||||
🎮 Commencer à jouer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- VICTORY MODAL -->
|
||||
<div class="victory-modal hidden" id="victory-modal">
|
||||
<div class="modal-content">
|
||||
@@ -196,7 +229,7 @@
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer>
|
||||
<p>© 2024 NextGN Formation - Memory Pictogrammes GHS</p>
|
||||
<p>© 2026 Gauthier Chombart & Nathan Chauwin<br>Tous droits réservés — Formations Certibiocide & Techniques — Formateurs indépendants</p>
|
||||
<p style="margin-top: 10px; opacity: 0.6;">Tous droits réservés - Formateurs indépendants</p>
|
||||
</footer>
|
||||
|
||||
|
||||
33
index.html
33
index.html
@@ -3,25 +3,25 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>NextGN Formation - Formations Certibiocide & Techniques</title>
|
||||
<title>Gauthier Chombart & Nathan Chauwin - Formations Certibiocide & Techniques</title>
|
||||
|
||||
<!-- SEO de base -->
|
||||
<meta name="description" content="Formations Certibiocide pratiques et interactives par des formateurs indépendants experts. Exercices, documentation technique sur les nuisibles et rapports de veille réglementaire.">
|
||||
<meta name="keywords" content="Certibiocide, formation biocides, hygiène professionnelle, nuisibles, désinfection, 3D, ESOD, formateurs indépendants">
|
||||
<meta name="author" content="Gauthier Chombart, Nathan Chauwin">
|
||||
<meta name="robots" content="index, follow">
|
||||
<link rel="canonical" href="https://VOTRE-DOMAINE.fr/">
|
||||
<link rel="canonical" href="https://nextgnformation.bsite.net/">
|
||||
|
||||
<!-- Open Graph (partage sur les réseaux sociaux et LinkedIn) -->
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="https://VOTRE-DOMAINE.fr/">
|
||||
<meta property="og:title" content="NextGN Formation - Formations Certibiocide & Techniques">
|
||||
<meta property="og:url" content="https://nextgnformation.bsite.net/">
|
||||
<meta property="og:title" content="Gauthier Chombart & Nathan Chauwin - Formations Certibiocide & Techniques">
|
||||
<meta property="og:description" content="Formations Certibiocide pratiques et interactives par des formateurs indépendants experts. Exercices, documentation technique sur les nuisibles et rapports de veille réglementaire.">
|
||||
<meta property="og:locale" content="fr_FR">
|
||||
|
||||
<!-- Twitter Card -->
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:title" content="NextGN Formation - Formations Certibiocide & Techniques">
|
||||
<meta name="twitter:title" content="Gauthier Chombart & Nathan Chauwin - Formations Certibiocide & Techniques">
|
||||
<meta name="twitter:description" content="Formations Certibiocide pratiques et interactives par des formateurs indépendants experts.">
|
||||
|
||||
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=DM+Sans:ital,wght@0,300;0,400;0,500;1,300&display=swap" rel="stylesheet">
|
||||
@@ -29,7 +29,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="logo">NextGN Formation</div>
|
||||
<div class="logo">Gauthier Chombart & Nathan Chauwin</div>
|
||||
<nav>
|
||||
<a href="#formations">Exercices interactifs</a>
|
||||
<a href="#documentation">Documentation</a>
|
||||
@@ -103,7 +103,7 @@
|
||||
<div class="formation-card">
|
||||
<div class="formation-header">
|
||||
<div class="formation-icon">📋</div>
|
||||
<h3 class="formation-title">FDS & Étiquettes</h3>
|
||||
<h3 class="formation-title">FDS, FT & Étiquettes</h3>
|
||||
<p class="formation-subtitle">Aller plus loin</p>
|
||||
</div>
|
||||
<div class="formation-body">
|
||||
@@ -137,6 +137,19 @@
|
||||
<a href="exercices/memory-pictogrammes/memory.html" class="formation-link">Jouer</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Correction : page unique pour tous les exercices -->
|
||||
<div class="formation-card">
|
||||
<div class="formation-header">
|
||||
<div class="formation-icon">✅</div>
|
||||
<h3 class="formation-title">Corriger un exercice</h3>
|
||||
<p class="formation-subtitle">Correction des rendus</p>
|
||||
</div>
|
||||
<div class="formation-body">
|
||||
<p class="formation-description">Déposez le PDF exporté par un groupe et obtenez la lecture de son rendu. Page unique de correction pour l'ensemble des exercices.</p>
|
||||
<a href="exercices/corriger-exercice.html" class="formation-link">Corriger</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -208,7 +221,7 @@
|
||||
<li>125+ offres d'emploi techniciens 3D</li>
|
||||
</ul>
|
||||
</div>
|
||||
<a href="veille/rapport-semaine-21.html" class="rapport-link">Consulter le rapport complet →</a>
|
||||
<a href="veille/rapports/veille-certibiocide-semaine-21.html" class="rapport-link">Consulter le rapport complet →</a>
|
||||
</div>
|
||||
|
||||
<!-- Semaine 20 -->
|
||||
@@ -226,7 +239,7 @@
|
||||
<li>Opportunités secteur 3D</li>
|
||||
</ul>
|
||||
</div>
|
||||
<a href="veille/rapport-semaine-20.html" class="rapport-link">Consulter le rapport complet →</a>
|
||||
<a href="veille/rapports/veille-certibiocide-semaine-20.html" class="rapport-link">Consulter le rapport complet →</a>
|
||||
</div>
|
||||
|
||||
<!-- Archive -->
|
||||
@@ -314,7 +327,7 @@
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2026 NextGN Formation - Formations Certibiocide & Techniques</p>
|
||||
<p>© 2026 Gauthier Chombart & Nathan Chauwin<br>Tous droits réservés — Formations Certibiocide & Techniques — Formateurs indépendants</p>
|
||||
<p style="margin-top: 10px; opacity: 0.6;">Tous droits réservés — Gauthier Chombart & Nathan Chauwin — Formateurs indépendants</p>
|
||||
</footer>
|
||||
|
||||
|
||||
@@ -419,7 +419,7 @@
|
||||
|
||||
<!-- HEADER -->
|
||||
<header>
|
||||
<div class="logo">NextGN Formation</div>
|
||||
<div class="logo">Gauthier Chombart & Nathan Chauwin</div>
|
||||
<nav>
|
||||
<a href="#formations">Exercices interactifs</a>
|
||||
<a href="#documentation">Documentation</a>
|
||||
@@ -799,7 +799,7 @@
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer>
|
||||
<p>© 2024 NextGN Formation - Rapport Veille Semaine 20</p>
|
||||
<p>© 2026 Gauthier Chombart & Nathan Chauwin<br>Tous droits réservés — Formations Certibiocide & Techniques — Formateurs indépendants</p>
|
||||
<p>Tous droits réservés - Formateur indépendant spécialisé en Certibiocide</p>
|
||||
</footer>
|
||||
|
||||
|
||||
@@ -419,7 +419,7 @@
|
||||
|
||||
<!-- HEADER -->
|
||||
<header>
|
||||
<div class="logo">NextGN Formation</div>
|
||||
<div class="logo">Gauthier Chombart & Nathan Chauwin</div>
|
||||
<nav>
|
||||
<a href="#formations">Exercices interactifs</a>
|
||||
<a href="#documentation">Documentation</a>
|
||||
@@ -799,7 +799,7 @@
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer>
|
||||
<p>© 2024 NextGN Formation - Rapport Veille Semaine 21</p>
|
||||
<p>© 2026 Gauthier Chombart & Nathan Chauwin<br>Tous droits réservés — Formations Certibiocide & Techniques — Formateurs indépendants</p>
|
||||
<p>Tous droits réservés - Formateur indépendant spécialisé en Certibiocide</p>
|
||||
</footer>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Veille Certibiocide — Semaine 23 | NextGN Formation</title>
|
||||
<title>Veille Certibiocide — Semaine 23 | Gauthier Chombart & Nathan Chauwin</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=DM+Sans:ital,wght@0,300;0,400;0,500;1,300&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
@@ -355,7 +355,7 @@
|
||||
|
||||
<!-- NAV -->
|
||||
<nav class="nav-header">
|
||||
<a href="index.html" class="header-logo"><span>NextGN</span> Formation</a>
|
||||
<a href="index.html" class="header-logo">Gauthier Chombart & Nathan Chauwin</a>
|
||||
<nav class="header-nav">
|
||||
<a href="index.html#formations">Exercices interactifs</a>
|
||||
<a href="index.html#about">À propos</a>
|
||||
@@ -800,7 +800,7 @@
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2026 NextGN Formation — Veille Certibiocide Semaine 23</p>
|
||||
<p>© 2026 Gauthier Chombart & Nathan Chauwin<br>Tous droits réservés — Formations Certibiocide & Techniques — Formateurs indépendants</p>
|
||||
<p style="margin-top:10px; opacity:0.6;">Tous droits réservés — Formateurs indépendants</p>
|
||||
</footer>
|
||||
|
||||
|
||||
@@ -356,7 +356,7 @@
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="nav-header">
|
||||
<a href="index.html" class="header-logo"><span>NextGN</span> Formation</a>
|
||||
<a href="index.html" class="header-logo">Gauthier Chombart & Nathan Chauwin</a>
|
||||
<nav class="header-nav" id="mainNav">
|
||||
<a href="index.html#formations">Exercices interactifs</a>
|
||||
<a href="index.html#about">À propos</a>
|
||||
@@ -790,7 +790,7 @@
|
||||
</div><!-- /container -->
|
||||
|
||||
<footer>
|
||||
<p>© 2026 NextGN Formation — Veille Certibiocide Semaine 24</p>
|
||||
<p>© 2026 Gauthier Chombart & Nathan Chauwin<br>Tous droits réservés — Formations Certibiocide & Techniques — Formateurs indépendants</p>
|
||||
<p style="margin-top:10px; opacity:0.6;">Tous droits réservés — Formateurs indépendants</p>
|
||||
</footer>
|
||||
|
||||
|
||||
@@ -375,7 +375,7 @@
|
||||
|
||||
<!-- NAV HEADER -->
|
||||
<nav class="nav-header">
|
||||
<a href="index.html" class="header-logo"><span>NextGN</span> Formation</a>
|
||||
<a href="index.html" class="header-logo">Gauthier Chombart & Nathan Chauwin</a>
|
||||
<button class="hamburger" id="hamburger" aria-label="Menu">
|
||||
<span></span><span></span><span></span>
|
||||
</button>
|
||||
@@ -704,7 +704,7 @@
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer>
|
||||
<p>© 2026 NextGN Formation - Veille Certibiocide Semaine 25</p>
|
||||
<p>© 2026 Gauthier Chombart & Nathan Chauwin<br>Tous droits réservés — Formations Certibiocide & Techniques — Formateurs indépendants</p>
|
||||
<p>Tous droits réservés - Formateurs indépendants</p>
|
||||
</footer>
|
||||
|
||||
|
||||
825
veille/rapports/veille-certibiocide-semaine-26.html
Normal file
825
veille/rapports/veille-certibiocide-semaine-26.html
Normal file
@@ -0,0 +1,825 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Veille Certibiocide — Semaine 26 | Gauthier Chombart & Nathan Chauwin</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=DM+Sans:ital,wght@0,300;0,400;0,500;1,300&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--teal: #0F6E56;
|
||||
--teal-mid: #1D9E75;
|
||||
--teal-light: #E1F5EE;
|
||||
--teal-dark: #085041;
|
||||
--amber: #BA7517;
|
||||
--amber-light: #FAEEDA;
|
||||
--amber-dark: #633806;
|
||||
--coral: #993C1D;
|
||||
--coral-mid: #D85A30;
|
||||
--coral-light: #FAECE7;
|
||||
--purple: #534AB7;
|
||||
--purple-light: #EEEDFE;
|
||||
--purple-dark: #3C3489;
|
||||
--blue: #185FA5;
|
||||
--blue-light: #E6F1FB;
|
||||
--bg: #F7F6F2;
|
||||
--white: #FFFFFF;
|
||||
--text: #1a1a18;
|
||||
--text-muted: #6b6a65;
|
||||
--border: rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
padding-top: 73px;
|
||||
background: var(--bg);
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
color: var(--text);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.nav-header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 70px;
|
||||
background: rgba(255,255,255,0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
border-bottom: 1px solid var(--border);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 40px;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-weight: 800;
|
||||
font-size: 20px;
|
||||
text-decoration: none;
|
||||
background: linear-gradient(135deg, var(--teal), var(--coral-mid));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.header-nav {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.header-nav a {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: var(--text-muted);
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
padding-bottom: 2px;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.header-nav a::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
background: var(--teal-mid);
|
||||
transition: width 0.25s ease;
|
||||
}
|
||||
|
||||
.header-nav a:hover { color: var(--teal); }
|
||||
.header-nav a:hover::after { width: 100%; }
|
||||
|
||||
.progress {
|
||||
height: 3px;
|
||||
background: var(--border);
|
||||
position: fixed;
|
||||
top: 70px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 999;
|
||||
}
|
||||
.progress-bar {
|
||||
height: 100%;
|
||||
background: var(--teal-mid);
|
||||
width: 0%;
|
||||
transition: width 0.1s ease;
|
||||
}
|
||||
|
||||
.hero {
|
||||
background: var(--teal-light);
|
||||
border-bottom: 2px solid var(--teal-mid);
|
||||
padding: 60px 40px 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hero-badge {
|
||||
display: inline-block;
|
||||
background: var(--teal-mid);
|
||||
color: var(--white);
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
padding: 6px 16px;
|
||||
border-radius: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-weight: 800;
|
||||
font-size: 2.6rem;
|
||||
color: var(--teal-dark);
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.hero-meta {
|
||||
font-size: 15px;
|
||||
color: var(--text-muted);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.hero-meta strong {
|
||||
color: var(--teal);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
padding: 0 24px 60px;
|
||||
}
|
||||
|
||||
.sommaire {
|
||||
background: var(--white);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.07);
|
||||
padding: 24px 28px;
|
||||
margin: 32px 0;
|
||||
position: sticky;
|
||||
top: 80px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.sommaire h3 {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.sommaire-links {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.sommaire-links a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--teal);
|
||||
text-decoration: none;
|
||||
background: var(--teal-light);
|
||||
padding: 5px 12px;
|
||||
border-radius: 20px;
|
||||
transition: background 0.2s, color 0.2s, transform 0.2s;
|
||||
}
|
||||
|
||||
.sommaire-links a:hover {
|
||||
background: var(--teal-mid);
|
||||
color: var(--white);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.attention-box {
|
||||
background: var(--amber-light);
|
||||
border-left: 4px solid var(--amber);
|
||||
border-radius: 10px;
|
||||
padding: 24px 28px;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
|
||||
.attention-box h2 {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 1.1rem;
|
||||
color: var(--amber-dark);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.attention-item {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.attention-num {
|
||||
flex-shrink: 0;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
background: var(--amber);
|
||||
color: var(--white);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.attention-item p {
|
||||
font-size: 14px;
|
||||
color: var(--amber-dark);
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.section {
|
||||
background: var(--white);
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.06);
|
||||
margin-bottom: 28px;
|
||||
overflow: hidden;
|
||||
animation: fadeIn 0.6s ease-out;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
.section-header {
|
||||
background: var(--teal-light);
|
||||
padding: 18px 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
border-bottom: 1px solid rgba(29,158,117,0.15);
|
||||
}
|
||||
|
||||
.section-header h2 {
|
||||
font-family: 'Syne', sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 1.05rem;
|
||||
color: var(--teal-dark);
|
||||
}
|
||||
|
||||
.section-header .emoji { font-size: 1.3rem; }
|
||||
|
||||
.section-body { padding: 20px 24px; }
|
||||
|
||||
.actu {
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.actu:last-child { border-bottom: none; padding-bottom: 0; }
|
||||
.actu:first-child { padding-top: 0; }
|
||||
|
||||
.actu-source {
|
||||
display: inline-block;
|
||||
background: var(--teal-mid);
|
||||
color: var(--white);
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
font-family: 'Syne', sans-serif;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
padding: 3px 10px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.actu p {
|
||||
font-size: 14px;
|
||||
line-height: 1.55;
|
||||
color: var(--text);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.actu-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.actu-date {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.actu-link {
|
||||
font-size: 12px;
|
||||
color: var(--teal-mid);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: transform 0.2s, color 0.2s;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.actu-link:hover {
|
||||
color: var(--teal-dark);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
footer {
|
||||
background: var(--text);
|
||||
color: var(--white);
|
||||
padding: 40px;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
footer p:last-child {
|
||||
margin-top: 10px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.nav-header {
|
||||
padding: 12px 20px;
|
||||
flex-wrap: wrap;
|
||||
height: auto;
|
||||
gap: 10px;
|
||||
}
|
||||
.header-nav { gap: 16px; flex-wrap: wrap; }
|
||||
body { padding-top: 100px; }
|
||||
.progress { top: 100px; }
|
||||
.hero { padding: 40px 20px 36px; }
|
||||
.hero h1 { font-size: 1.8rem; }
|
||||
.container { padding: 0 16px 40px; }
|
||||
.sommaire { position: static; }
|
||||
.section-header h2 { font-size: 0.95rem; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="nav-header">
|
||||
<a href="index.html" class="header-logo">Gauthier Chombart & Nathan Chauwin</a>
|
||||
<nav class="header-nav">
|
||||
<a href="index.html#formations">Exercices interactifs</a>
|
||||
<a href="index.html#about">À propos</a>
|
||||
<a href="index.html#contact">Contact</a>
|
||||
</nav>
|
||||
</nav>
|
||||
|
||||
<div class="progress"><div class="progress-bar" id="progressBar"></div></div>
|
||||
|
||||
<div class="hero">
|
||||
<div class="hero-badge">📋 Rapport de veille hebdomadaire</div>
|
||||
<h1>Veille Certibiocide<br>Semaine 26 — 2026</h1>
|
||||
<p class="hero-meta">
|
||||
<strong>Semaine du 23 au 29 juin 2026</strong> ·
|
||||
Généré le 29 juin 2026 · Gauthier Chombart & Nathan Chauwin
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<nav class="sommaire">
|
||||
<h3>📑 Sommaire</h3>
|
||||
<div class="sommaire-links">
|
||||
<a href="#reglementaire">⚖️ Réglementaire</a>
|
||||
<a href="#marche-formation">🎓 Marché formation</a>
|
||||
<a href="#nuisibles">🐀 Nuisibles & ESOD</a>
|
||||
<a href="#desinfection">🧴 Désinfection</a>
|
||||
<a href="#opportunites">💡 Opportunités</a>
|
||||
<a href="#innovation">🔬 Innovation</a>
|
||||
<a href="#europe">🇪🇺 Veille européenne</a>
|
||||
<a href="#rh">👥 RH & Concurrence</a>
|
||||
<a href="#attention">📌 Points d'attention</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- POINTS D'ATTENTION -->
|
||||
<div class="attention-box" id="attention">
|
||||
<h2>📌 Points d'attention — Semaine 26</h2>
|
||||
<div class="attention-item">
|
||||
<div class="attention-num">1</div>
|
||||
<p><strong>Certibiocide Désinfectants pleinement en vigueur depuis janvier 2026 :</strong> les décideurs, acheteurs et distributeurs de biocides désinfectants professionnels doivent être certifiés. Vérifiez que vos stagiaires maîtrisent les 3 catégories (Désinfectants TP2/3/4, Nuisibles TP14/18/20, Autres produits TP8/15/21) et l'obligation de déclaration annuelle avant le 31 mars. Qualiopi obligatoire pour le FAFCEA depuis le 1er juillet 2026.</p>
|
||||
</div>
|
||||
<div class="attention-item">
|
||||
<div class="attention-num">2</div>
|
||||
<p><strong>CPF : reste à charge à 150 € depuis le 2 avril 2026.</strong> Ce changement peut freiner les inscriptions CPF. Les demandeurs d'emploi restent exonérés. Anticipez cet argument dans vos entretiens de vente et orientez les salariés vers un financement OPCO (prise en charge jusqu'à 100 % pour les TPE/PME < 50 salariés).</p>
|
||||
</div>
|
||||
<div class="attention-item">
|
||||
<div class="attention-num">3</div>
|
||||
<p><strong>Appel d'offres BOAMP Fos-sur-Mer — clôture le 2 juillet 2026 :</strong> à transmettre à vos partenaires prestataires. Le secteur 3D affiche une demande structurelle en recrutement (>25 offres actives sur Indeed au 11 juin), ce qui renforce l'argumentaire de vos formations Certibiocide Nuisibles.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 1. RÉGLEMENTAIRE -->
|
||||
<section class="section" id="reglementaire">
|
||||
<div class="section-header">
|
||||
<span class="emoji">⚖️</span>
|
||||
<h2>Réglementaire — AMM, BPR, obligations Certibiocide</h2>
|
||||
</div>
|
||||
<div class="section-body">
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">ANSES</span>
|
||||
<p>Plusieurs <strong>décisions de modifications administratives d'AMM biocides</strong> publiées le 17 juin 2026 : <em>ANTI-MITES ALIMENTAIRES-GEA</em> (signé 08/06), <em>SANYTOL LACTIC SA-APP</em> (signé 04/06), <em>BELOX</em> (signé 05/06). Ces décisions portent sur des ajustements de compositions ou d'usages autorisés, sans retrait de marché.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">17 juin 2026</span>
|
||||
<a href="https://www.anses.fr/fr/decisions_biocide" class="actu-link" target="_blank" rel="noopener">→ Registre AMM biocides ANSES</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">ANSES</span>
|
||||
<p>Modifications administratives publiées les 10 et 17 juin pour <strong>TWIST-TIE MD2 INPEST, PHEROMONE DROP FOR CLOTHES MOTHS, AUTAN KIDS SPRAY</strong> et <strong>BRODITEC P-29F</strong>. Principalement des ajustements des conditions d'emploi et des mises en garde. Aucun retrait complet d'AMM identifié cette semaine.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">Juin 2026</span>
|
||||
<a href="https://www.anses.fr/fr/decisions_biocide" class="actu-link" target="_blank" rel="noopener">→ Registre AMM biocides ANSES</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Réglementation FR</span>
|
||||
<p>La <strong>triple catégorisation du Certibiocide</strong> est opérationnelle depuis le 1er janvier 2026. Les distributeurs ont l'obligation d'enregistrer le numéro de certificat de leurs acheteurs professionnels. La <strong>déclaration annuelle</strong> à l'application gouvernementale est à effectuer avant le 31 mars de chaque année.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">En vigueur depuis le 01/01/2026</span>
|
||||
<a href="https://climalife.com/fr/certibiocide-reglementation-2026/" class="actu-link" target="_blank" rel="noopener">→ Climalife – synthèse réglementaire</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">ECHA / Commission UE</span>
|
||||
<p>L'<strong>évaluation complète du BPR</strong> (UE) n° 528/2012 se poursuit après la consultation publique du 11 décembre 2025 au 5 mars 2026. Les conclusions alimenteront la révision du règlement, ciblant les retards d'approbation des substances actives et les inefficacités du marché sur 12 ans de mise en œuvre.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">Suivi 2026</span>
|
||||
<a href="https://en.reach24h.com/news/industry-news/disinfectant-biocide/eu-bpr-evaluation-public-consultation" class="actu-link" target="_blank" rel="noopener">→ REACH24H – évaluation BPR</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 2. MARCHÉ FORMATION -->
|
||||
<section class="section" id="marche-formation">
|
||||
<div class="section-header">
|
||||
<span class="emoji">🎓</span>
|
||||
<h2>Marché formation — Qualiopi, CPF, OPCO</h2>
|
||||
</div>
|
||||
<div class="section-body">
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Service-Public.fr</span>
|
||||
<p>Depuis le <strong>2 avril 2026</strong>, le reste à charge CPF est fixé à <strong>150 € par dossier de formation</strong>, quel que soit le montant. Les demandeurs d'emploi inscrits à France Travail restent exonérés. Ce changement impacte directement les inscriptions CPF aux formations Certibiocide pour les salariés.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">Depuis le 2 avril 2026</span>
|
||||
<a href="https://www.service-public.gouv.fr/particuliers/actualites/A18831" class="actu-link" target="_blank" rel="noopener">→ Service-public.fr – CPF 2026</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">OPCO / PDC</span>
|
||||
<p>Le budget national du <strong>PDC 2026 recule à 521 M€</strong> (vs 550 M€ en 2025). Les TPE/PME < 50 salariés restent prioritaires avec une prise en charge jusqu'à <strong>100 % des coûts pédagogiques</strong> via OPCO. Les formations Certibiocide pour les petites structures 3D restent donc finançables à taux plein.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2026</span>
|
||||
<a href="https://formaltic.fr/financement-opco-formations-2026/" class="actu-link" target="_blank" rel="noopener">→ Formaltic – financement OPCO 2026</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">FAFCEA / Qualiopi</span>
|
||||
<p>Depuis le <strong>1er juillet 2026</strong>, Qualiopi est strictement obligatoire pour les financements FAFCEA (artisans). Cette date butoir est atteinte : les organismes de formation Certibiocide non certifiés Qualiopi sont désormais exclus des financements FAFCEA. À vérifier impérativement si vous intervenez auprès d'artisans.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">En vigueur au 01/07/2026</span>
|
||||
<a href="https://csfc-federation.org/blog/qualiopi-devient-obligatoire-pour-les-financements-fafcea-des-2026/" class="actu-link" target="_blank" rel="noopener">→ CSFC Fédération</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Branches pro / Urssaf</span>
|
||||
<p>Depuis <strong>janvier 2026</strong>, les branches professionnelles peuvent confier la collecte de leurs contributions conventionnelles aux Urssaf. Les formations en <strong>période de reconversion</strong> sont désormais cofinançables via OPCO ou CPF, ouvrant de nouvelles opportunités pour les reconversions vers les métiers 3D/biocides.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">Depuis janvier 2026</span>
|
||||
<a href="https://up-academie.com/cpf-et-dispositifs-de-financement/" class="actu-link" target="_blank" rel="noopener">→ UP Académie – dispositifs 2026</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 3. NUISIBLES & ESOD -->
|
||||
<section class="section" id="nuisibles">
|
||||
<div class="section-header">
|
||||
<span class="emoji">🐀</span>
|
||||
<h2>Nuisibles & ESOD — Moustique tigre, frelon, rongeurs, punaises</h2>
|
||||
</div>
|
||||
<div class="section-body">
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Santé publique — Castres</span>
|
||||
<p>Nuit du <strong>10 au 11 juin 2026</strong> : opération sanitaire d'urgence à <strong>Castres (Tarn)</strong> suite à un cas importé de <strong>chikungunya</strong>. Le moustique tigre (<em>Aedes albopictus</em>), présent localement, peut transmettre le virus à partir d'un patient virémique, justifiant une démoustication nocturne en centre-ville.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">11 juin 2026</span>
|
||||
<a href="https://solution-nuisible.fr/actualites/chikungunya-a-castres-pourquoi-le-moustique-tigre-a-declenche-une-intervention-nocturne/" class="actu-link" target="_blank" rel="noopener">→ Solution-nuisible.fr</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Municipalité Royan</span>
|
||||
<p>Royan ouvre un dispositif d'<strong>aide de 50 € par nid de frelon asiatique</strong> détruit (1er juin – 30 novembre 2026), dans le cadre du plan national de lutte lancé en mars 2026. Ce modèle de subvention communale est à surveiller : d'autres collectivités pourraient l'adopter, générant une demande accrue pour les prestataires agréés.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">Juin 2026</span>
|
||||
<a href="https://solution-nuisible.fr/actualites/a-royan-une-aide-de-50-euros-face-a-la-recrudescence-du-frelon-asiatique/" class="actu-link" target="_blank" rel="noopener">→ Solution-nuisible.fr</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Étude 2026</span>
|
||||
<p><strong>62 % des Français</strong> déclarent avoir été touchés par des nuisibles à domicile. Entre 2021 et 2025 : guêpes/frelons ×2,8 — rongeurs ×2,5 — punaises de lit ×2,1. Ces données confirment la tension structurelle du marché 3D et la légitimité des formations Certibiocide face à une demande en forte hausse.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2026</span>
|
||||
<a href="https://monimmeuble.com/actualite/nuisibles-a-domicile-62-des-francais-touches-un-fleau-qui-explose" class="actu-link" target="_blank" rel="noopener">→ Monimmeuble.com</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Lyon Capitale</span>
|
||||
<p>La métropole lyonnaise interroge sa capacité à coordonner une réponse cohérente face à la prolifération printanière 2026 des espèces invasives (frelon asiatique, moustique tigre, processionnaire). La demande en prestataires agréés et techniciens formés Certibiocide s'intensifie dans les grandes métropoles.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">Printemps 2026</span>
|
||||
<a href="https://www.lyoncapitale.fr/actualite/lyon-la-guerre-contre-les-especes-invasives-aura-t-elle-lieu" class="actu-link" target="_blank" rel="noopener">→ Lyon Capitale</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 4. DÉSINFECTION -->
|
||||
<section class="section" id="desinfection">
|
||||
<div class="section-header">
|
||||
<span class="emoji">🧴</span>
|
||||
<h2>Désinfection — Normes AFNOR, produits homologués, alternatives</h2>
|
||||
</div>
|
||||
<div class="section-body">
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Réglementation 2026</span>
|
||||
<p>Depuis le <strong>1er janvier 2026</strong>, le <strong>Certibiocide Désinfectants</strong> (TP2/3/4) est obligatoire pour les décideurs, acheteurs et distributeurs de désinfectants professionnels. Formation de 7h, QCM de 30 questions (seuil : 20/30), certificat nominatif valable 5 ans. L'obligation concerne aussi les entreprises de propreté utilisant des désinfectants biocides.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">En vigueur depuis le 01/01/2026</span>
|
||||
<a href="https://www.monde-proprete.com/certibiocide-desinfectant-obligation" class="actu-link" target="_blank" rel="noopener">→ Le Monde de la Propreté</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">AFNOR</span>
|
||||
<p>La norme <strong>NF U43-500</strong> (bonnes pratiques d'application des produits biocides) est en cours de révision 2026. L'AFNOR confirme le maintien des normes de référence en désinfection : <strong>EN 14476</strong> (virucide) et <strong>EN 14885</strong> (référentiel européen désinfectants). Ces normes structurent les contenus des formations Certibiocide Désinfectants.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2026</span>
|
||||
<a href="https://norminfo.afnor.org/consultation/nf-u43-500/bonnes-pratiques-dapplication-des-produits-phytosanitaires-et-biocides-maitrise-des-applications-de-produits-phytosanitaires/108423" class="actu-link" target="_blank" rel="noopener">→ AFNOR – consultation NF U43-500</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">BPR / ECHA</span>
|
||||
<p>Nouvelles décisions BPR d'<strong>avril 2026</strong> sur des substances actives désinfectantes clés : <strong>cyperméthrine, DBNPA, libérateurs de formaldéhyde et éthanol</strong>. Ces mises à jour de conformité affectent les produits biocides TP2/3/4 disponibles sur le marché UE. Les supports de formation Certibiocide Désinfectants doivent être actualisés.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">Avril 2026</span>
|
||||
<a href="https://en.reach24h.com/news/industry-news/disinfectant-biocide/eu-brp-key-biocidal-active-substances-update" class="actu-link" target="_blank" rel="noopener">→ REACH24H – substances actives</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">ProdHyBase</span>
|
||||
<p><strong>ProdHyBase</strong> reste la référence française pour identifier les normes AFNOR validées par chaque désinfectant (dossiers fournis par les distributeurs). Outil pédagogique central pour les formations Certibiocide Désinfectants : permet aux stagiaires de vérifier l'homologation d'un produit TP2/3/4 et ses normes de validation.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">Permanent</span>
|
||||
<a href="https://www.prodhybase.fr/norme_generalite.html" class="actu-link" target="_blank" rel="noopener">→ ProdHyBase</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 5. OPPORTUNITÉS -->
|
||||
<section class="section" id="opportunites">
|
||||
<div class="section-header">
|
||||
<span class="emoji">💡</span>
|
||||
<h2>Opportunités — Appels d'offres BOAMP, CPF, secteurs demandeurs</h2>
|
||||
</div>
|
||||
<div class="section-body">
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">BOAMP</span>
|
||||
<p><strong>⚡ Urgent — Clôture le 02/07/2026 :</strong> Appel d'offres de la ville de <strong>Fos-sur-Mer</strong> pour des prestations de lutte contre les nuisibles en 2 lots (Lot 1 : 3D — dératisation, désinsectisation, désinfection ; Lot 2 : dératisation par prédation). À transmettre immédiatement à vos partenaires prestataires.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">Clôture 02/07/2026</span>
|
||||
<a href="https://www.francemarches.com/appel-offre/3boamp2651311-2026-prestations-lutte-contre" class="actu-link" target="_blank" rel="noopener">→ FranceMarches – Fos-sur-Mer</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">BOAMP</span>
|
||||
<p>Accord-cadre mono-attributaire pour des <strong>prestations de prévention et lutte contre les nuisibles et l'insalubrité</strong> (réf. 3/boamp/264816-2026) — montant maximum annuel : <strong>50 000 € HT</strong>. Ce type de marché à bons de commande est particulièrement accessible pour les petites structures indépendantes du secteur 3D.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2026</span>
|
||||
<a href="https://www.francemarches.com/appel-offre/3boamp264816-2026-prestations-prevention-lutte" class="actu-link" target="_blank" rel="noopener">→ FranceMarches – accord-cadre nuisibles</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">BOAMP — Oise</span>
|
||||
<p>Le <strong>Département de l'Oise</strong> a lancé un marché multi-sites pour des missions 3D sur ses bâtiments départementaux, collèges publics et réseau routier (réf. 3/boamp/2616972). Volume significatif pour les prestataires régionaux — nécessite des opérateurs certifiés Certibiocide Nuisibles.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">Envoi : 13/02/2026</span>
|
||||
<a href="https://www.francemarches.com/appel-offre/3boamp2616972-2026-missions-deratisation-desinsectisation" class="actu-link" target="_blank" rel="noopener">→ FranceMarches – Département Oise</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">BOAMP — Musées Paris</span>
|
||||
<p>Les <strong>Musées d'Orsay et de l'Orangerie (Paris 7e)</strong> ont lancé un marché de traitement 3D pour leurs locaux (réf. 3/boamp/266207). La multiplication des marchés institutionnels (patrimoine, collectivités, établissements publics) souligne la demande en professionnels certifiés capables d'intervenir dans des environnements sensibles.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2026</span>
|
||||
<a href="https://www.francemarches.com/appel-offre/3boamp266207-2026-marche-traitement-deratisation" class="actu-link" target="_blank" rel="noopener">→ FranceMarches – Musées d'Orsay</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 6. INNOVATION -->
|
||||
<section class="section" id="innovation">
|
||||
<div class="section-header">
|
||||
<span class="emoji">🔬</span>
|
||||
<h2>Innovation — Bioinsecticides, IoT, IA</h2>
|
||||
</div>
|
||||
<div class="section-body">
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">UE — LIFE BioPest</span>
|
||||
<p>Le projet européen <strong>LIFE BioPest (2024-2027)</strong> finance le développement de <strong>bioinsecticides à base de champignons entomopathogènes</strong> pour remplacer les pyréthrinoïdes en milieu urbain. Ces substances biologiques pourraient à terme faire l'objet d'AMM biocides et modifier les pratiques enseignées en formation Certibiocide Nuisibles.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2024-2027 (en cours)</span>
|
||||
<a href="https://www.hamelin.info/actus/desinsectisation/lutte-antiparasitaire-innovation-tradition/" class="actu-link" target="_blank" rel="noopener">→ Hamelin – innovation antiparasitaire</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Anticimex France</span>
|
||||
<p>Les <strong>pièges connectés IoT couplés à l'IA</strong> se déploient massivement dans l'industrie agroalimentaire et la restauration en 2026. Alertes en temps réel, anticipation des schémas saisonniers, tableaux de bord de données. Anticimex France détaille cette intégration IA + IoT + data pour une lutte préventive optimisée.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2026</span>
|
||||
<a href="https://www.anticimex.fr/blog/lutte-nuisibles-connectee-ia-iot-data/" class="actu-link" target="_blank" rel="noopener">→ Anticimex France – IoT & IA</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Nuisible Control</span>
|
||||
<p>Les tendances 2026 orientent le marché vers une <strong>dératisation éthique</strong> : méthodes biologiques (prédation, champignons), réduction des rodenticides de 2e génération, montée des alternatives aux biocides chimiques. Les formateurs Certibiocide doivent intégrer ces évolutions dans leurs supports pédagogiques pour rester pertinents.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2026</span>
|
||||
<a href="https://nuisible-control.fr/actualites/tendance-deratisation-ethique-et-efficace" class="actu-link" target="_blank" rel="noopener">→ Nuisible Control – tendances 2026</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Application-IoT.fr</span>
|
||||
<p>Les <strong>pièges connectés IoT révolutionnent la gestion des nuisibles dans l'industrie alimentaire</strong> : capteurs intégrés, transmission de données en temps réel, réduction des passages physiques de contrôle. Cette technologie constitue un argument de vente fort pour les prestataires 3D formés et à jour sur les outils connectés.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2026</span>
|
||||
<a href="https://www.application-iot.fr/industrie-4-0/les-pieges-connectes-revolutionnent-la-gestion-des-nuisibles-dans-lindustrie-alimentaire/" class="actu-link" target="_blank" rel="noopener">→ Application-IoT.fr</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 7. VEILLE EUROPÉENNE -->
|
||||
<section class="section" id="europe">
|
||||
<div class="section-header">
|
||||
<span class="emoji">🇪🇺</span>
|
||||
<h2>Veille européenne — BPR, EFSA, résistances insecticides</h2>
|
||||
</div>
|
||||
<div class="section-body">
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Commission européenne</span>
|
||||
<p>L'<strong>évaluation complète du BPR</strong> après 12 ans de mise en œuvre se poursuit. La consultation publique (11 décembre 2025 – 5 mars 2026) a recueilli les contributions des parties prenantes. Les conclusions orienteront une révision ciblant les retards d'approbation des substances actives et la simplification administrative du régime biocides.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">En cours — 2026</span>
|
||||
<a href="https://en.reach24h.com/news/industry-news/disinfectant-biocide/eu-bpr-evaluation-public-consultation" class="actu-link" target="_blank" rel="noopener">→ REACH24H – évaluation BPR</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">ECHA — Substances actives</span>
|
||||
<p>Décisions d'<strong>avril 2026</strong> sur les substances actives clés : <strong>cyperméthrine</strong> (TP14, TP18), <strong>DBNPA, libérateurs de formaldéhyde, éthanol</strong>. Ces mises à jour de conformité impactent directement le statut des produits biocides sur le marché UE. Points à intégrer dans les contenus de formation Certibiocide.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">Avril 2026</span>
|
||||
<a href="https://en.reach24h.com/news/industry-news/disinfectant-biocide/eu-brp-key-biocidal-active-substances-update" class="actu-link" target="_blank" rel="noopener">→ REACH24H – BPR substances actives</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">ECHA — Programme d'examen</span>
|
||||
<p>Le programme d'examen des <strong>substances actives biocides existantes</strong> continue en 2026 avec la publication d'un nouveau règlement délégué de mise à jour. Le suivi de l'avancement est crucial : certaines substances utilisées en formation (TP14/18/20) pourraient être restreintes ou retirées à l'issue des évaluations.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2026</span>
|
||||
<a href="https://www.atoutchimie.eu/avancement-du-programme-dexamen-europeen-des-substances-actives-existantes" class="actu-link" target="_blank" rel="noopener">→ Atout Chimie – programme d'examen</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">GB BPR (post-Brexit)</span>
|
||||
<p>Les renouvellements de <strong>substances actives sous le GB BPR sont attendus en 2026</strong>. Pertinent pour les entreprises françaises exportant vers le Royaume-Uni ou travaillant avec des fournisseurs britanniques de produits biocides. À surveiller pour anticiper d'éventuelles divergences réglementaires UE/UK.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2026</span>
|
||||
<a href="https://ecomundo.eu/en" class="actu-link" target="_blank" rel="noopener">→ Ecomundo – GB BPR 2026</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 8. RH & CONCURRENCE -->
|
||||
<section class="section" id="rh">
|
||||
<div class="section-header">
|
||||
<span class="emoji">👥</span>
|
||||
<h2>RH & Concurrence — Emploi 3D, RNCP, mouvements du secteur</h2>
|
||||
</div>
|
||||
<div class="section-body">
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Indeed — 11 juin 2026</span>
|
||||
<p>Au <strong>11 juin 2026</strong>, Indeed recense <strong>> 25 offres actives pour des techniciens dératisation 3D</strong> et > 75 offres en CDI pour techniciens dératisation/désinsectisation. Le secteur recrute structurellement avec des embauches directes à l'issue du stage — argument fort pour les formations Certibiocide orientées insertion.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">11 juin 2026</span>
|
||||
<a href="https://fr.indeed.com/q-deratisation-3d-emplois.html" class="actu-link" target="_blank" rel="noopener">→ Indeed – offres 3D</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">France Compétences</span>
|
||||
<p>Le <strong>CQP Technicien applicateur — RNCP 36313 (niveau 3, équivalent CAP)</strong> reste la certification de référence. Il intègre le Certibiocide Nuisibles dans son programme (3 mois dont 3 semaines de stage). Accessible demandeurs d'emploi et reconversions. Vérifiez la date de renouvellement RNCP pour anticiper toute échéance.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2026</span>
|
||||
<a href="https://www.francecompetences.fr/recherche/rncp/36313/" class="actu-link" target="_blank" rel="noopener">→ France Compétences – RNCP 36313</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">Secteur 3D</span>
|
||||
<p>Le secteur 3D compte <strong>> 1 200 entreprises actives</strong> en France pour un CA supérieur à <strong>500 millions d'euros</strong>. La pénurie de techniciens qualifiés est structurelle. Les formateurs Certibiocide indépendants bénéficient d'un contexte porteur : forte demande en formation initiale et continue, amplifiée par les obligations réglementaires 2026.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2026</span>
|
||||
<a href="https://www.je-change-de-metier.com/fiche-metier-deratiseur" class="actu-link" target="_blank" rel="noopener">→ Je-change-de-métier.com</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actu">
|
||||
<span class="actu-source">CS3D / ProSane</span>
|
||||
<p>L'association <strong>CS3D / ProSane</strong> continue de structurer la profession : référencement des techniciens, annuaire professionnel, formations éligibles au CQP. Partenaire potentiel pour les formateurs Certibiocide indépendants cherchant à développer leur réseau et leur visibilité auprès des entreprises 3D recruteuses.</p>
|
||||
<div class="actu-meta">
|
||||
<span class="actu-date">2026</span>
|
||||
<a href="https://www.association-prosane.fr/technicien-specalise-maitrise-nuisibles" class="actu-link" target="_blank" rel="noopener">→ CS3D ProSane</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>© 2026 Gauthier Chombart & Nathan Chauwin<br>Tous droits réservés — Formations Certibiocide & Techniques — Formateurs indépendants</p>
|
||||
<p>Tous droits réservés — Formateurs indépendants</p>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
window.addEventListener('scroll', () => {
|
||||
const scrolled = (window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100;
|
||||
document.getElementById('progressBar').style.width = Math.min(scrolled, 100) + '%';
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
376
veille/rapports/veille-certibiocide-semaine-28.html
Normal file
376
veille/rapports/veille-certibiocide-semaine-28.html
Normal file
@@ -0,0 +1,376 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Veille Certibiocide — Semaine 28 (06-12 juillet 2026)</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=DM+Sans:ital,wght@0,300;0,400;0,500;1,300&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--teal: #0F6E56;
|
||||
--teal-mid: #1D9E75;
|
||||
--teal-light: #E1F5EE;
|
||||
--teal-dark: #085041;
|
||||
--amber: #BA7517;
|
||||
--amber-light: #FAEEDA;
|
||||
--amber-dark: #633806;
|
||||
--coral: #993C1D;
|
||||
--coral-mid: #D85A30;
|
||||
--coral-light: #FAECE7;
|
||||
--purple: #534AB7;
|
||||
--purple-light: #EEEDFE;
|
||||
--purple-dark: #3C3489;
|
||||
--blue: #185FA5;
|
||||
--blue-light: #E6F1FB;
|
||||
--bg: #F7F6F2;
|
||||
--white: #FFFFFF;
|
||||
--text: #1a1a18;
|
||||
--text-muted: #6b6a65;
|
||||
--border: rgba(0,0,0,0.1);
|
||||
}
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
padding-top: 70px;
|
||||
background: var(--bg);
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
color: var(--text);
|
||||
line-height: 1.6;
|
||||
}
|
||||
h1, h2, h3 { font-family: 'Syne', sans-serif; }
|
||||
|
||||
/* Header */
|
||||
.nav-header {
|
||||
position: fixed; top: 0; left: 0; right: 0; height: 70px;
|
||||
background: rgba(255,255,255,0.95); backdrop-filter: blur(10px);
|
||||
border-bottom: 1px solid var(--border); z-index: 1000;
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 0 32px;
|
||||
}
|
||||
.header-logo {
|
||||
font-family: 'Syne', sans-serif; font-weight: 800; font-size: 20px;
|
||||
text-decoration: none;
|
||||
background: linear-gradient(90deg, var(--teal), var(--coral-mid));
|
||||
-webkit-background-clip: text; background-clip: text; color: transparent;
|
||||
}
|
||||
.header-logo span { font-weight: 800; }
|
||||
.header-nav { display: flex; gap: 28px; }
|
||||
.header-nav a {
|
||||
font-family: 'Syne', sans-serif; font-size: 12px; text-transform: uppercase;
|
||||
letter-spacing: 0.5px; color: var(--text); text-decoration: none;
|
||||
position: relative; padding-bottom: 4px;
|
||||
}
|
||||
.header-nav a::after {
|
||||
content: ''; position: absolute; left: 0; bottom: 0; width: 0; height: 2px;
|
||||
background: var(--teal-mid); transition: width 0.2s ease;
|
||||
}
|
||||
.header-nav a:hover::after { width: 100%; }
|
||||
|
||||
/* Progress bar */
|
||||
.progress { height: 3px; background: var(--border); position: fixed; top: 70px; left: 0; right: 0; z-index: 999; }
|
||||
.progress-bar { height: 100%; background: var(--teal-mid); width: 0%; transition: width 0.3s ease; }
|
||||
|
||||
.wrap { max-width: 900px; margin: 0 auto; padding: 40px 24px 20px; }
|
||||
|
||||
/* Hero */
|
||||
.hero {
|
||||
background: var(--teal-light); border: 1px solid var(--teal-mid);
|
||||
border-radius: 14px; padding: 36px 40px; margin-bottom: 32px;
|
||||
}
|
||||
.badge {
|
||||
display: inline-block; background: var(--teal); color: var(--white);
|
||||
font-family: 'Syne', sans-serif; font-size: 12px; text-transform: uppercase;
|
||||
letter-spacing: 0.5px; padding: 6px 14px; border-radius: 20px; margin-bottom: 14px;
|
||||
}
|
||||
.hero h1 { font-size: 30px; font-weight: 800; color: var(--teal-dark); margin-bottom: 8px; }
|
||||
.hero p { color: var(--text-muted); font-size: 14px; }
|
||||
|
||||
/* Sommaire */
|
||||
.sommaire {
|
||||
position: sticky; top: 90px; background: var(--white); border: 1px solid var(--border);
|
||||
border-radius: 10px; padding: 18px 22px; margin-bottom: 32px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.04); z-index: 10;
|
||||
}
|
||||
.sommaire h3 { font-size: 13px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); margin-bottom: 10px; }
|
||||
.sommaire-links { display: flex; flex-wrap: wrap; gap: 10px 18px; }
|
||||
.sommaire-links a {
|
||||
font-size: 13px; color: var(--teal-dark); text-decoration: none; font-weight: 500;
|
||||
}
|
||||
.sommaire-links a:hover { text-decoration: underline; }
|
||||
|
||||
/* Points d'attention */
|
||||
.attention {
|
||||
background: var(--amber-light); border-left: 4px solid var(--amber);
|
||||
border-radius: 10px; padding: 24px 28px; margin-bottom: 40px;
|
||||
}
|
||||
.attention h2 { font-size: 20px; color: var(--amber-dark); margin-bottom: 14px; }
|
||||
.attention ol { margin-left: 20px; color: var(--text); }
|
||||
.attention li { margin-bottom: 10px; font-size: 14.5px; }
|
||||
|
||||
/* Sections */
|
||||
.section {
|
||||
background: var(--white); border-radius: 10px; margin-bottom: 28px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.05); overflow: hidden;
|
||||
animation: fadeIn 0.6s ease-out;
|
||||
scroll-margin-top: 100px;
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
.section-header {
|
||||
background: var(--teal-light); padding: 16px 24px;
|
||||
font-family: 'Syne', sans-serif; font-weight: 700; font-size: 17px; color: var(--teal-dark);
|
||||
}
|
||||
.section-body { padding: 20px 24px; }
|
||||
.news { padding: 14px 0; border-bottom: 1px solid var(--border); }
|
||||
.news:last-child { border-bottom: none; }
|
||||
.news-source {
|
||||
display: inline-block; background: var(--teal-light); color: var(--teal-dark);
|
||||
font-family: 'Syne', sans-serif; font-size: 11px; text-transform: uppercase;
|
||||
letter-spacing: 0.3px; padding: 3px 10px; border-radius: 20px; margin-bottom: 6px;
|
||||
}
|
||||
.news p { font-size: 14.5px; margin: 6px 0; }
|
||||
.news-meta { font-size: 12.5px; color: var(--text-muted); }
|
||||
.news-meta a { color: var(--teal); text-decoration: none; transition: transform 0.2s ease; display: inline-block; }
|
||||
.news-meta a:hover { transform: translateY(-1px); text-decoration: underline; }
|
||||
|
||||
.note {
|
||||
background: var(--amber-light); border: 1px solid var(--amber);
|
||||
color: var(--amber-dark); border-radius: 8px; padding: 10px 14px;
|
||||
font-size: 13.5px; margin: 10px 0;
|
||||
}
|
||||
|
||||
footer {
|
||||
background: var(--text); color: var(--white); padding: 40px; font-size: 13px; text-align: center;
|
||||
margin-top: 40px;
|
||||
}
|
||||
footer p:first-child { opacity: 0.9; }
|
||||
footer p:last-child { margin-top: 10px; opacity: 0.6; }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.nav-header { flex-direction: column; height: auto; padding: 12px 20px; align-items: flex-start; gap: 8px; }
|
||||
body { padding-top: 110px; }
|
||||
.progress { top: 110px; }
|
||||
.header-nav { gap: 16px; flex-wrap: wrap; }
|
||||
.hero { padding: 24px 22px; }
|
||||
.hero h1 { font-size: 22px; }
|
||||
.sommaire { position: static; }
|
||||
.section-body, .section-header { padding-left: 18px; padding-right: 18px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="nav-header">
|
||||
<a href="index.html" class="header-logo">Gauthier Chombart & Nathan Chauwin</a>
|
||||
<nav class="header-nav">
|
||||
<a href="index.html#formations">Exercices interactifs</a>
|
||||
<a href="index.html#about">À propos</a>
|
||||
<a href="index.html#contact">Contact</a>
|
||||
</nav>
|
||||
</nav>
|
||||
<div class="progress"><div class="progress-bar" id="progressBar"></div></div>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
<div class="hero">
|
||||
<span class="badge">Semaine 28</span>
|
||||
<h1>Veille Certibiocide</h1>
|
||||
<p>Semaine du 06 au 12 juillet 2026 — Rapport de veille réglementaire et technique</p>
|
||||
</div>
|
||||
|
||||
<div class="sommaire">
|
||||
<h3>Sommaire</h3>
|
||||
<div class="sommaire-links">
|
||||
<a href="#reglementaire">⚖️ Réglementaire</a>
|
||||
<a href="#formation">🎓 Marché formation</a>
|
||||
<a href="#nuisibles">🐀 Nuisibles & ESOD</a>
|
||||
<a href="#desinfection">🧴 Désinfection</a>
|
||||
<a href="#opportunites">💡 Opportunités</a>
|
||||
<a href="#innovation">🔬 Innovation</a>
|
||||
<a href="#europe">🇪🇺 Veille européenne</a>
|
||||
<a href="#rh">👥 RH & Concurrence</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="attention">
|
||||
<h2>📌 Points d'attention</h2>
|
||||
<ol>
|
||||
<li><strong>Qualiopi désormais obligatoire pour le FAFCEA</strong> — depuis le 1er juillet 2026, la période transitoire est terminée : seuls les organismes certifiés Qualiopi peuvent être financés pour les formations destinées aux artisans.</li>
|
||||
<li><strong>Nouveau règlement européen (UE) 2026/1165</strong> — entré en vigueur le 15 juin 2026, il prolonge jusqu'au 31/12/2030 la protection des données de certains dossiers de substances actives biocides : à intégrer dans les modules réglementaires BPR.</li>
|
||||
<li><strong>Marchés publics 3D/4D actifs</strong> — plusieurs appels d'offres BOAMP en cours (Oise, Fos-sur-Mer, Carrières-sous-Poissy, Le Cannet) : fenêtre à surveiller pour des partenariats avec des prestataires en recherche de formation Certibiocide.</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="section" id="reglementaire">
|
||||
<div class="section-header">⚖️ Réglementaire</div>
|
||||
<div class="section-body">
|
||||
<div class="news">
|
||||
<span class="news-source">ANSES</span>
|
||||
<p>Autorisation de mise sur le marché du produit biocide ZANZA SPRAY (n° AMM FR-2026-0040, signature du 18/06/2026). Publication au registre le 1er juillet 2026.</p>
|
||||
<div class="news-meta"><em>01/07/2026</em> — <a href="https://www.anses.fr/fr/decisions_biocide" target="_blank" rel="noopener">Registre des AMM biocides — ANSES</a></div>
|
||||
</div>
|
||||
<div class="news">
|
||||
<span class="news-source">ANSES</span>
|
||||
<p>Retrait de plusieurs produits de traitement du bois (XILIX GEL BS, 18V33CP-PE, INDULINE SW-900 IT, TRAITEMENT BOIS EXTERIEUR NUANCE, V33 TRAITEMENT BOIS MULTI USAGES, XILIX 1000, XYL SGR 2002). Décisions signées le 15/06/2026, publiées le 24/06/2026.</p>
|
||||
<div class="news-meta"><em>24/06/2026</em> — <a href="https://www.anses.fr/fr/decisions_biocide" target="_blank" rel="noopener">Registre des AMM biocides — ANSES</a></div>
|
||||
</div>
|
||||
<div class="news">
|
||||
<span class="news-source">ANSES</span>
|
||||
<p>Arrêté du 4 juin 2026 fixant les redevances biocides dues à l'ANSES pour toute demande déposée en France au titre du règlement (UE) 528/2012.</p>
|
||||
<div class="news-meta"><em>04/06/2026</em> — <a href="https://www.anses.fr/fr/content/demarches-produits-biocides" target="_blank" rel="noopener">Démarches produits biocides — ANSES</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" id="formation">
|
||||
<div class="section-header">🎓 Marché formation</div>
|
||||
<div class="section-body">
|
||||
<div class="news">
|
||||
<span class="news-source">FAFCEA</span>
|
||||
<p>Depuis le 1er juillet 2026, seuls les organismes certifiés Qualiopi sont éligibles aux financements FAFCEA pour les formations destinées aux artisans. La période de transition s'est achevée le 30 juin 2026.</p>
|
||||
<div class="news-meta"><em>01/07/2026</em> — <a href="https://csfc-federation.org/blog/qualiopi-devient-obligatoire-pour-les-financements-fafcea-des-2026/" target="_blank" rel="noopener">CSFC-Fédération</a></div>
|
||||
</div>
|
||||
<div class="news">
|
||||
<span class="news-source">France Compétences</span>
|
||||
<p>La révision du Référentiel National Qualité, socle de Qualiopi, entre dans sa phase finale : consultations en cours avec certificateurs et organismes de formation.</p>
|
||||
<div class="news-meta"><em>2026</em> — <a href="https://fresh-management.fr/qualiopi-2026-changements-organisme-formation/" target="_blank" rel="noopener">Fresh Management</a></div>
|
||||
</div>
|
||||
<div class="note">⚠️ Aucune donnée chiffrée récente et vérifiée sur le CPF ou les OPCO EP n'a été trouvée cette semaine au-delà des statistiques 2024 déjà connues (~880 000 contrats d'apprentissage financés).</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" id="nuisibles">
|
||||
<div class="section-header">🐀 Nuisibles & ESOD</div>
|
||||
<div class="section-body">
|
||||
<div class="news">
|
||||
<span class="news-source">Veille sanitaire</span>
|
||||
<p>Le moustique tigre est désormais implanté durablement dans 83 des 96 départements métropolitains (plus de 86 %), avec une progression des cas de dengue et de chikungunya à transmission locale.</p>
|
||||
<div class="news-meta"><em>2026</em> — <a href="https://izipest.com/blog/top-3-especes-envahissantes-france-2026/" target="_blank" rel="noopener">IZIPest</a></div>
|
||||
</div>
|
||||
<div class="news">
|
||||
<span class="news-source">Frelon asiatique</span>
|
||||
<p>Un plan national de lutte contre le frelon asiatique et les autres espèces invasives a été lancé en mars 2026. Le frelon asiatique contribuerait à environ 20 % de la mortalité des colonies d'abeilles domestiques.</p>
|
||||
<div class="news-meta"><em>mars 2026</em> — <a href="https://www.lyoncapitale.fr/actualite/lyon-la-guerre-contre-les-especes-invasives-aura-t-elle-lieu" target="_blank" rel="noopener">Lyon Capitale</a></div>
|
||||
</div>
|
||||
<div class="note">⚠️ Aucune donnée récente vérifiée via sources officielles (ANSES, INRAE) sur les rongeurs résistants aux anticoagulants cette semaine.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" id="desinfection">
|
||||
<div class="section-header">🧴 Désinfection</div>
|
||||
<div class="section-body">
|
||||
<div class="news">
|
||||
<span class="news-source">Certibiocide</span>
|
||||
<p>Depuis le 1er janvier 2026, l'obtention du Certibiocide est obligatoire pour tout professionnel utilisant, achetant ou distribuant des produits biocides à usage professionnel. La formation dure 7 heures et le certificat est valable 5 ans.</p>
|
||||
<div class="news-meta"><em>01/01/2026</em> — <a href="https://tbcformation.com/certibiocide-2026-nouveautes-reglementation-desinfection/" target="_blank" rel="noopener">TBC Formation</a></div>
|
||||
</div>
|
||||
<div class="news">
|
||||
<span class="news-source">AFNOR</span>
|
||||
<p>Le cadre normatif reste structuré autour de NF EN 14885 (produits biocides de désinfection), NF EN 14476 (activité virucide) et NF T72-281 (désinfection par voie aérienne). Aucune révision de ces normes n'a été identifiée cette semaine.</p>
|
||||
<div class="news-meta"><em>2026</em> — <a href="https://norminfo.afnor.org/norme/NF%20U43-500/bonnes-pratiques-dapplication-des-produits-phytosanitaires-et-biocides-maitrise-des-applications-de-produits-phytosanitaires/79450" target="_blank" rel="noopener">AFNOR Norm'Info</a></div>
|
||||
</div>
|
||||
<div class="note">⚠️ Aucun nouveau produit homologué spécifique signalé cette semaine par les sources consultées.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" id="opportunites">
|
||||
<div class="section-header">💡 Opportunités</div>
|
||||
<div class="section-body">
|
||||
<div class="news">
|
||||
<span class="news-source">BOAMP — Oise</span>
|
||||
<p>Marché de missions de dératisation, désinsectisation, désinfection et traitement spécifique sur les sites et le réseau routier du département de l'Oise. Notification de l'accord-cadre prévue en juillet 2026.</p>
|
||||
<div class="news-meta"><em>juillet 2026</em> — <a href="https://www.francemarches.com/appel-offre/3boamp2616972-2026-missions-deratisation-desinsectisation" target="_blank" rel="noopener">France Marchés</a></div>
|
||||
</div>
|
||||
<div class="news">
|
||||
<span class="news-source">BOAMP — Fos-sur-Mer</span>
|
||||
<p>Marché de prestations de lutte contre les nuisibles sur la voirie et les bâtiments communaux, réparti en 2 lots. Date limite de remise des offres : 2 juillet 2026.</p>
|
||||
<div class="news-meta"><em>02/07/2026</em> — <a href="https://www.francemarches.com/appel-offre/3boamp2651311-2026-prestations-lutte-contre" target="_blank" rel="noopener">France Marchés</a></div>
|
||||
</div>
|
||||
<div class="news">
|
||||
<span class="news-source">BOAMP — Carrières-sous-Poissy</span>
|
||||
<p>Marché de prestations anti-nuisibles 4D (dératisation, désinfection, désinsectisation, dépigeonnisation) actuellement en consultation.</p>
|
||||
<div class="news-meta"><em>2026</em> — <a href="https://www.francemarches.com/appel-offre/3boamp2632494-2026-prestation-anti-nuisibles" target="_blank" rel="noopener">France Marchés</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" id="innovation">
|
||||
<div class="section-header">🔬 Innovation</div>
|
||||
<div class="section-body">
|
||||
<div class="news">
|
||||
<span class="news-source">LIFE BioPest</span>
|
||||
<p>Le projet européen LIFE BioPest (2024-2027) finance le développement de bioinsecticides à base de champignons entomopathogènes destinés à remplacer les pyréthrinoïdes en zone urbaine.</p>
|
||||
<div class="news-meta"><em>2024-2027</em> — <a href="https://www.application-iot.fr/industrie-4-0/les-pieges-connectes-revolutionnent-la-gestion-des-nuisibles-dans-lindustrie-alimentaire/" target="_blank" rel="noopener">Application IoT</a></div>
|
||||
</div>
|
||||
<div class="news">
|
||||
<span class="news-source">Groupe Berkem</span>
|
||||
<p>Le piège connecté Novaterm® combine intelligence artificielle et superactivateur végétal pour la lutte antiparasitaire.</p>
|
||||
<div class="news-meta"><em>2026</em> — <a href="https://www.hamelin.info/actus/deratisation/lutte-anti-nuisible-et-revolution-numerique/" target="_blank" rel="noopener">Hamelin</a></div>
|
||||
</div>
|
||||
<div class="news">
|
||||
<span class="news-source">Anticimex</span>
|
||||
<p>Déploiement de pièges connectés couplés à des plateformes de gestion de données (IA, IoT) dans l'industrie agroalimentaire, avec alertes en temps réel et anticipation des pics saisonniers.</p>
|
||||
<div class="news-meta"><em>2026</em> — <a href="https://www.anticimex.fr/blog/lutte-nuisibles-connectee-ia-iot-data/" target="_blank" rel="noopener">Anticimex</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" id="europe">
|
||||
<div class="section-header">🇪🇺 Veille européenne</div>
|
||||
<div class="section-body">
|
||||
<div class="news">
|
||||
<span class="news-source">Commission européenne</span>
|
||||
<p>Le règlement (UE) 2026/1165, entré en vigueur le 15 juin 2026, modifie le BPR et prolonge la protection des données de certains dossiers de substances actives jusqu'au 31 décembre 2030, afin de compenser les retards du programme d'examen.</p>
|
||||
<div class="news-meta"><em>15/06/2026</em> — <a href="https://www.cehtra.com/post/amendment-bpr-for-data-protection-extension-enters-into-force" target="_blank" rel="noopener">Cehtra</a></div>
|
||||
</div>
|
||||
<div class="news">
|
||||
<span class="news-source">ECHA</span>
|
||||
<p>Publication de mises à jour réglementaires concernant plusieurs substances actives biocides clés : cyperméthrine, DBNPA, certains libérateurs de formaldéhyde et éthanol.</p>
|
||||
<div class="news-meta"><em>2026</em> — <a href="https://en.reach24h.com/news/industry-news/disinfectant-biocide/eu-brp-key-biocidal-active-substances-update" target="_blank" rel="noopener">REACH24H</a></div>
|
||||
</div>
|
||||
<div class="news">
|
||||
<span class="news-source">Commission européenne</span>
|
||||
<p>Une consultation publique européenne est ouverte pour évaluer les 12 années de mise en œuvre du règlement biocides (BPR), en vue d'une possible révision future.</p>
|
||||
<div class="news-meta"><em>2026</em> — <a href="https://en.reach24h.com/news/industry-news/disinfectant-biocide/eu-bpr-evaluation-public-consultation" target="_blank" rel="noopener">REACH24H</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" id="rh">
|
||||
<div class="section-header">👥 RH & Concurrence</div>
|
||||
<div class="section-body">
|
||||
<div class="news">
|
||||
<span class="news-source">CS3D</span>
|
||||
<p>Le CQP Technicien applicateur en maîtrise des nuisibles est inscrit au RNCP au niveau 3 (équivalent CAP). Le parcours dure 3 mois, incluant un stage de 3 semaines en entreprise et le Certibiocide.</p>
|
||||
<div class="news-meta"><em>2026</em> — <a href="https://www.paritarisme-emploi-formation.fr/le-cqp-maitrise-des-nuisibles-professionnaliser" target="_blank" rel="noopener">Paritarisme Emploi Formation</a></div>
|
||||
</div>
|
||||
<div class="news">
|
||||
<span class="news-source">Secteur 3D</span>
|
||||
<p>Plus de 1 200 entreprises actives en France pour un chiffre d'affaires supérieur à 500 millions d'euros. Le secteur recrute en continu et propose fréquemment un CDI à l'issue du stage.</p>
|
||||
<div class="news-meta"><em>2026</em> — <a href="https://www.hamelin.info/metier/environnement-de-travail/cqp-maitrise-des-nuisibles/" target="_blank" rel="noopener">Hamelin</a></div>
|
||||
</div>
|
||||
<div class="news">
|
||||
<span class="news-source">Marché de l'emploi</span>
|
||||
<p>Des offres de technicien 3D Certibiocide sont actives, notamment en Île-de-France (environ 1 752 € brut en CDD).</p>
|
||||
<div class="news-meta"><em>11/06/2026</em> — <a href="https://fr.indeed.com/q-deratisation-3d-emplois.html" target="_blank" rel="noopener">Indeed</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>© 2026 Gauthier Chombart & Nathan Chauwin<br>Tous droits réservés — Formations Certibiocide & Techniques — Formateurs indépendants</p>
|
||||
<p>Tous droits réservés - Formateurs indépendants</p>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
window.addEventListener('scroll', () => {
|
||||
const scrolled = (window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100;
|
||||
document.getElementById('progressBar').style.width = scrolled + '%';
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -353,7 +353,7 @@
|
||||
|
||||
<!-- HEADER -->
|
||||
<header>
|
||||
<div class="logo">NextGN Formation</div>
|
||||
<div class="logo">Gauthier Chombart & Nathan Chauwin</div>
|
||||
<nav>
|
||||
<a href="../../index.html">Exercices interactifs</a>
|
||||
<a href="../../index.html#documentation">Documentation</a>
|
||||
@@ -503,7 +503,7 @@
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer>
|
||||
<p>© 2026 NextGN Formation - Formations Certibiocide & Techniques</p>
|
||||
<p>© 2026 Gauthier Chombart & Nathan Chauwin<br>Tous droits réservés — Formations Certibiocide & Techniques — Formateurs indépendants</p>
|
||||
<p style="margin-top: 10px; opacity: 0.6;">Tous droits réservés — Gauthier Chombart & Nathan Chauwin — Formateurs indépendants</p>
|
||||
</footer>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user