QUIZZIFS / REGLUE.html
MMOON's picture
Update REGLUE.html
8482dd0 verified
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Portail Réglementation UE – Complet & Responsive</title>
<style>
:root{
--bg-main: #f8fafc;
--bg-panel: #ffffff;
--bg-side: #f1f5f9;
--text-primary: #0f172a;
--text-secondary: #475569;
--text-light: #64748b;
--line: #e2e8f0;
--accent-blue: #2563eb;
--accent-blue-light: #eff6ff;
--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body{
margin:0;
font-family: var(--font-sans);
background: var(--bg-main);
color: var(--text-primary);
display: grid;
grid-template-columns: 340px 1fr;
height: 100vh;
overflow: hidden;
}
/* --- Sidebar --- */
aside{
background: var(--bg-side);
border-right: 1px solid var(--line);
display: flex;
flex-direction: column;
height: 100vh;
transition: transform 0.3s ease-in-out;
flex-shrink: 0;
}
.aside-header { padding: 16px 20px; }
.brand { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 16px; }
.brand h1 { font-size: 22px; margin: 0; }
.search { position: relative; margin-bottom: 16px; }
.search input, #theme-filter {
all: unset; box-sizing: border-box;
width: 100%;
background: var(--bg-panel);
border: 1px solid var(--line);
border-radius: 8px;
padding: 10px 12px;
font-size: 14px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
#theme-filter {
background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%3Cpath%20d%3D%22M5%208l5%205%205-5H5z%22%20fill%3D%22%2364748b%22/%3E%3C/svg%3E');
background-repeat: no-repeat;
background-position: right 8px center;
background-size: 1.2em;
padding-right: 2.5em;
cursor: pointer;
}
.search input { padding-left: 36px; }
.search-icon { position: absolute; top: 11px; left: 12px; color: var(--text-light); }
label { font-size: 13px; font-weight: 600; color: var(--text-secondary); display: block; margin-bottom: 6px; }
.menu-container {
flex: 1;
overflow-y: auto;
padding: 0 12px 20px 20px;
}
nav { display: flex; flex-direction: column; gap: 6px; }
.item {
display: block;
padding: 12px 14px;
border-radius: 8px;
cursor: pointer;
border: 1px solid transparent;
transition: background-color 0.2s ease, border-color 0.2s ease;
}
.item:hover { background: #e9eef5; }
.item.active {
background: var(--bg-panel);
border-color: var(--line);
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.item-header { display:flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.item h4 { margin: 0; font-size: 15px; line-height: 1.5; color: var(--text-primary); }
.item code { font-size: 11px; color: var(--text-secondary); background: #e0e7ee; padding: 2px 5px; border-radius: 4px; flex-shrink: 0;}
.item .badges { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.badge { font-size: 10px; font-weight: 500; padding: 4px 8px; border-radius: 6px; background: #e0e7ee; }
.aside-footer { padding: 16px 20px; border-top: 1px solid var(--line); font-size: 12px; color: var(--text-light); }
/* --- Main Content --- */
main {
display: flex;
flex-direction: column;
height: 100vh;
}
.main-header {
padding: 12px 24px;
background: var(--bg-panel);
border-bottom: 1px solid var(--line);
flex-shrink: 0;
display: flex;
align-items: center;
gap: 16px;
}
.main-header h2 { margin: 0; font-size: 24px; line-height: 1.2; }
.main-header .meta { display: flex; flex-wrap: wrap; gap: 12px; color: var(--text-light); font-size: 13px; margin-top: 4px; }
.content-nav {
position: sticky; top: 0;
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
border-bottom: 1px solid var(--line);
padding: 0 24px;
z-index: 10;
flex-shrink: 0;
}
.content-nav-links { display: flex; gap: 4px; }
.content-nav a {
color: var(--text-secondary);
text-decoration: none;
padding: 14px 12px;
font-size: 14px;
font-weight: 600;
border-bottom: 2px solid transparent;
transition: color 0.2s ease, border-color 0.2s ease;
cursor: pointer;
}
.content-nav a:hover { color: var(--text-primary); }
.content-nav a.active {
color: var(--accent-blue);
border-bottom-color: var(--accent-blue);
}
.content-wrapper {
flex: 1;
overflow-y: auto;
padding: 32px;
}
.content-section {
padding-top: 16px;
margin-bottom: 32px;
}
.content-section > h3 {
font-size: 22px;
color: var(--text-primary);
margin: 0 0 20px 0;
display: flex; align-items: center; gap: 10px;
padding-bottom: 10px;
border-bottom: 1px solid var(--line);
}
.card {
background: var(--bg-panel);
border: 1px solid var(--line);
border-radius: 12px;
padding: 24px;
margin-bottom: 16px;
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.03);
}
.card h4 { margin: 0 0 12px; font-size: 18px; }
.card ul { margin: 0; padding-left: 20px; font-size: 16px; line-height: 1.7; }
.card li { margin-bottom: 10px; }
.btn-link {
display: inline-flex; align-items: center; gap: 8px; text-decoration: none; color: var(--accent-blue);
background: var(--accent-blue-light); border: 1px solid var(--accent-blue-light);
padding: 10px 14px; border-radius: 8px; font-size: 14px; font-weight: 600;
}
.links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 10px; }
/* --- Mobile-specific & Menu Toggles --- */
#menu-toggle, #menu-close {
display: none;
background: none; border: none; font-size: 20px; color: var(--text-secondary); cursor: pointer; padding: 4px;
}
#overlay {
display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: 99;
}
/* --- Responsive Breakpoint --- */
@media (max-width: 1024px) {
body { grid-template-columns: 1fr; }
aside {
position: fixed;
top: 0; left: 0; z-index: 100;
transform: translateX(-100%);
width: 320px;
box-shadow: 0 0 40px rgba(0,0,0,0.1);
}
aside.open { transform: translateX(0); }
#menu-toggle, #menu-close { display: inline-block; }
.content-wrapper { padding: 24px 16px; }
.main-header h2 { font-size: 20px; }
.content-section > h3 { font-size: 20px; }
.card { padding: 16px; }
.card h4 { font-size: 16px; }
.card ul { font-size: 15px; }
}
</style>
</head>
<body>
<div id="overlay"></div>
<!-- ==================== SIDEBAR ==================== -->
<aside id="sidebar">
<div class="aside-header">
<div class="brand">
<h1>Réglementation UE</h1>
<button id="menu-close" aria-label="Fermer le menu">&times;</button>
</div>
<div class="search">
<svg class="search-icon" width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><path fill-rule="evenodd" d="M9.965 11.026a5 5 0 1 1 1.06-1.06l2.755 2.754a.75.75 0 1 1-1.06 1.06l-2.755-2.754ZM10.5 7a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Z" clip-rule="evenodd"/></svg>
<input id="q" placeholder="Rechercher un texte..." aria-label="Rechercher"/>
</div>
<div>
<label for="theme-filter">Filtrer par thème</label>
<select id="theme-filter"></select>
</div>
</div>
<div class="menu-container">
<nav id="menu" aria-label="Liste des textes"></nav>
</div>
<div class="aside-footer">
Outil de consultation. Source : EUR-Lex.
</div>
</aside>
<!-- ==================== MAIN CONTENT ==================== -->
<main>
<div class="main-header" role="banner">
<button id="menu-toggle" aria-label="Ouvrir le menu">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3 12H21M3 6H21M3 18H21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</button>
<div>
<h2 id="title">Sélectionnez un texte pour commencer</h2>
<div class="meta" id="meta"></div>
</div>
</div>
<div class="content-nav">
<div class="content-nav-links" id="content-nav-links">
<a data-target="s-resume" class="active">Résumé & Portée</a>
<a data-target="s-exigences">Exigences & Audit</a>
<a data-target="s-refs">Références</a>
</div>
</div>
<div class="content-wrapper" id="content-wrapper">
<!-- Content will be injected here -->
</div>
</main>
<script>
/** =================== Données (Exhaustives, inspirées de votre fichier) =================== **/
const DATA = [
/* ---- Cadre + Hygiène + Contrôles ---- */
{
id:"178/2002",
titre:"Règlement (CE) n° 178/2002 – Principes généraux (Food Law)",
celex:"02002R0178",
categorie:["Cadre général","Traçabilité","Rappel/Retrait"],
statut:"V",
maj:"2022-07-01",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02002R0178-20220701"}],
resume:[
"Analyse des risques, précaution, transparence; responsabilité première des exploitants.",
"Obligation de traçabilité ‘un pas en arrière/avant’ et de retrait/rappel si risque.",
"EFSA & RASFF pour l’évaluation/alerte rapide."
],
exigences:[
"Procédure documentée de gestion d’incident: détection, évaluation, retrait/rappel, notification autorités.",
"Traçabilité amont/aval opérationnelle (<4h pour fournir les infos pendant contrôle)."
],
audit:[
"Tester un scénario de retrait/rappel (exercice) avec délais et preuves.",
"Échantillon traçabilité: lot amont puis aval; mesure du temps d’obtention."
],
maj_points:[ "Harmonisé avec 2017/625 pour les contrôles officiels." ]
},
{
id:"852/2004",
titre:"Règlement (CE) n° 852/2004 – Hygiène des denrées",
celex:"02004R0852",
categorie:["Hygiène","PRP","HACCP"],
statut:"V",
maj:"2021-03-24",
liens:[
{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02004R0852-20210324"},
{label:"Communication 2022/C 355/01 (HACCP)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:52022XC0916(01)"}
],
resume:[
"PRP/BPH obligatoires: locaux, équipements, hygiène du personnel, eau, nettoyage, nuisibles, déchets, etc.",
"Procédures HACCP proportionnées aux risques; flexibilité possible selon activités."
],
exigences:[
"Validation des mesures de maîtrise (température, temps, nettoyabilité, allergènes).",
"Programme de prérequis documenté (plans, fréquences, vérifications)."
],
audit:[
"Revue des PRP, tendances (analyses environnementales, efficacité nettoyage).",
"Preuves de validation HACCP & revalidation suite à changements."
],
maj_points:[ "Guidances 2016/2022 sur flexibilité et mise en œuvre pratique." ]
},
{
id:"2017/625",
titre:"Règlement (UE) 2017/625 – Contrôles officiels",
celex:"02017R0625",
categorie:["Contrôles officiels","Fraude","Import"],
statut:"V",
maj:"2022-01-28",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02017R0625-20220128"}],
resume:[
"Cadre intégré pour les contrôles officiels; approche basée sur les risques et lutte anti‑fraude.",
"Règles d’import en PCF; transparence des résultats agrégés."
],
exigences:[
"Disponibilité des documents/accès; coopération avec l’autorité compétente.",
"Respect des exigences d’import (documents, certificats)."
],
audit:[ "Vérifier préparation dossier contrôle et conformité PCF pour importateurs." ],
maj_points:[ "Complété par 2019/624 (viandes, bivalves)." ]
},
{
id:"2073/2005",
titre:"Règlement (CE) n° 2073/2005 – Critères microbiologiques",
celex:"02005R2073",
categorie:["Microbiologie","Vérification","HACCP"],
statut:"V",
maj:"2020-03-08",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02005R2073-20200308"}],
resume:[
"Critères de sécurité vs d’hygiène des procédés; plans d’échantillonnage (n, c, m, M).",
"Gestion: retrait/rappel pour critères de sécurité; corrections process pour hygiène."
],
exigences:[
"Listeria monocytogenes dans PAM: < 100 ufc/g pendant DLC si croissance contrôlée; 0 ufc/25 g avant sortie si croissance possible.",
"Plan d’échantillonnage défini (n, c, m, M) et méthodes normalisées (ISO)."
],
audit:[
"Vérifier matrices/critères applicables; tendances; revalidation si dérive.",
"Challenge-tests/études de croissance si nécessaire pour PAM."
],
maj_points:[ "Suivre mises à jour annexes et avis EFSA." ]
},
{
id:"2023/915",
titre:"Règlement (UE) 2023/915 – Contaminants (refonte)",
celex:"32023R0915",
categorie:["Contaminants","ALARA"],
statut:"V",
maj:"2023-05-05",
liens:[{label:"EUR‑Lex (texte)", url:"https://eur-lex.europa.eu/legal-content/fr/TXT/?uri=CELEX:32023R0915"}],
resume:[
"Refonte des teneurs maximales (mycotoxines, métaux lourds, dioxines/PCB, PAH, HCAs…).",
"Principe ALARA; 1881/2006 abrogé."
],
exigences:[
"Plans de contrôle ciblés; méthodes conformes aux règlements d’échantillonnage (ex. 333/2007).",
"Gestion stricte des non‑conformités (blocage/retrait; pas de décontamination chimique)."
],
audit:[
"Vérifier matrice de risques contaminants + fréquences/LOQ.",
"Preuves de conformité laboratoire (accréditation ISO 17025)."
],
maj_points:[ "Entrée en application 25/05/2023; mises à jour ciblées possibles." ]
},
{
id:"333/2007",
titre:"Règlement (CE) n° 333/2007 – Échantillonnage/méthodes contaminants",
celex:"02007R0333",
categorie:["Méthodes","Contaminants"],
statut:"V",
maj:"2023-01-01",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02007R0333-20230101"}],
resume:[
"Plans de prélèvement officiels et critères de performance analytiques (r, RSD, LOQ, MU)."
],
exigences:[
"Respect des schémas d’échantillonnage par lot/taille; homogénéisation; conservation.",
"Validation méthode (trueness, precision, recovery) et incertitude mesurée."
],
audit:[ "Vérifier SOP d’échantillonnage et rapports d’aptitude (PT)." ],
maj_points:[ ]
},
{
id:"1935/2004",
titre:"Règlement (CE) n° 1935/2004 – Matériaux au contact (FCM)",
celex:"02004R1935",
categorie:["FCM","Traçabilité","Déclaration de conformité"],
statut:"V",
maj:"2021-03-27",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02004R1935-20210327"}],
resume:[
"Principe d’inertie; pas de transfert compromettant la sécurité, la composition ou l’odeur/goût.",
"Déclaration de conformité (DoC), traçabilité FCM, identification ‘verre & fourchette’."
],
exigences:[
"Dossier technique (DoC, migrations globale/spécifique, NIAS le cas échéant).",
"BPF obligatoires (2023/2006) couvrant toute la fabrication."
],
audit:[
"Vérifier DoC + rapports d’essais; contrôle fournisseurs/matériaux.",
"Validation nettoyage et usage prévu."
],
maj_points:[ "Interactions avec 10/2011 (plastiques) et 2022/1616 (recyclés)." ]
},
{
id:"10/2011",
titre:"Règlement (UE) n° 10/2011 – Plastiques FCM",
celex:"02011R0010",
categorie:["FCM","Plastiques"],
statut:"V",
maj:"2023-08-01",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02011R0010-20230801"}],
resume:[
"Listes d’Union des substances autorisées (monomères, additifs) + SML/OML.",
"Règles d’essai/migration et scénarios de contact/temps/température."
],
exigences:[
"Conformité formulation vs Union list; SML/OML respectées; évaluation NIAS.",
"DoC détaillée avec simulations/essais et conditions d’usage."
],
audit:[ "Contrôle fournisseurs, traçabilité formulations, essais tiers." ],
maj_points:[ "Mises à jour régulières des annexes (vérifier la dernière version)." ]
},
{
id:"2022/1616",
titre:"Règlement (UE) 2022/1616 – Plastiques recyclés FCM",
celex:"02022R1616",
categorie:["FCM","Plastiques","Recyclage"],
statut:"V",
maj:"2022-09-20",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02022R1616-20220920"}],
resume:[
"Autorisation des procédés de recyclage; maîtrise contamination; traçabilité chaîne.",
"Challenge-tests pour démontrer la décontamination."
],
exigences:[
"Utiliser seulement des procédés autorisés; documentation/contrôles spécifiques.",
"Contrat de qualité amont/aval; traçabilité des intrants."
],
audit:[ "Vérifier statut d’autorisation du procédé; preuves opérationnelles." ],
maj_points:[ "Remplace 282/2008; période de transition." ]
},
{
id:"2023/2006",
titre:"Règlement (CE) n° 2023/2006 – BPF FCM",
celex:"02006R2023",
categorie:["FCM","BPF"],
statut:"V",
maj:"2008-04-17",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02006R2023-20080417"}],
resume:[ "BPF obligatoires pour la fabrication des FCM; système qualité documenté." ],
exigences:[ "Procédures, enregistrements, maîtrise des changements, traçabilité lot." ],
audit:[ "Vérifier conformité du système qualité BPF et preuves de formation." ],
maj_points:[ ]
},
{
id:"450/2009",
titre:"Règlement (CE) n° 450/2009 – Matériaux actifs/intelligents",
celex:"02009R0450",
categorie:["FCM","Actifs/Intelligents"],
statut:"V",
maj:"2019-12-09",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02009R0450-20191209"}],
resume:[
"Cadre spécifique pour matériaux/objets actifs et intelligents (MOAI) au contact.",
"Substances libérées/adsorbées: conformité substances autorisées et OML/SML."
],
exigences:[
"Étiquetage spécifique (‘actif/intelligent’), information sur fonction; pas de mise en danger du consommateur.",
"Substances actives/intelligentes sur liste autorisée; migration sous contrôle."
],
audit:[
"Vérifier autorisation substances actives; scénarios d’usage; conformité migration."
],
maj_points:[ "Coordination avec 1935/2004 et mesures spécifiques (ex. 10/2011 si plastique)." ]
},
{
id:"1829/2003",
titre:"Règlement (CE) n° 1829/2003 – Denrées & aliments pour animaux génétiquement modifiés",
celex:"02003R1829",
categorie:["OGM","Autorisation","Étiquetage"],
statut:"V",
maj:"2019-07-26",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02003R1829-20190726"}],
resume:[
"Procédure d’autorisation centralisée des OGM/produits OGM pour l’alimentation humaine/animale.",
"Exigences d’étiquetage des denrées contenant/consistant en OGM ou produites à partir d’OGM."
],
exigences:[
"Pas de mise sur le marché sans autorisation; conditions d’utilisation et suivi post‑market si requis.",
"Étiquetage obligatoire; exemptions possibles si présence fortuite/techniquement inévitable ≤ 0,9 %."
],
audit:[
"Vérifier statut d’autorisation des ingrédients/produits; preuves fournisseurs.",
"Contrôler l’étiquetage et la maîtrise des contaminations croisées."
],
maj_points:[ ]
},
{
id:"1830/2003",
titre:"Règlement (CE) n° 1830/2003 – Traçabilité & étiquetage OGM",
celex:"02003R1830",
categorie:["OGM","Traçabilité","Étiquetage"],
statut:"V",
maj:"2014-04-09",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02003R1830-20140409"}],
resume:[
"Traçabilité des OGM et des denrées produites à partir d’OGM tout au long de la chaîne.",
"Obligations d’identification (codes uniques), documents à transmettre opérateur→opérateur."
],
exigences:[
"Transmission des informations obligatoires à chaque étape; conservation ≥ 5 ans.",
"Seuil d’étiquetage 0,9 % pour présence fortuite/techniquement inévitable."
],
audit:[ "Vérifier flux d’information OGM (réceptions, ventes) et archivage 5 ans." ],
maj_points:[ ]
},
{
id:"1169/2011",
titre:"Règlement (UE) n° 1169/2011 – Information consommateurs (INCO)",
celex:"02011R1169",
categorie:["Étiquetage","Allergènes","Nutrition"],
statut:"V",
maj:"2018-01-01",
liens:[
{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02011R1169-20180101"},
{label:"2018/775 – ingrédient primaire", url:"https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02018R0775-20190609"}
],
resume:[
"Mentions obligatoires (dénomination, ingrédients, allergènes, QUID, DLC/DDM, lot, nutrition…), lisibilité, origine dans certains cas.",
"Règles spécifiques sur l’ingrédient primaire (cohérence origine)."
],
exigences:[
"Taille de police ≥ 1,2 mm (x‑height); mise en évidence des allergènes dans la liste des ingrédients.",
"Origine obligatoire pour certaines viandes; cohérence ‘ingrédient primaire’."
],
audit:[
"Circuit de validation/archivage maquettes; revue médias digitaux (e‑commerce)."
],
maj_points:[ "Guidance Commission 2020/C 32/01 sur l’ingrédient primaire." ]
},
{
id:"1333/2008",
titre:"Règlement (CE) n° 1333/2008 – Additifs alimentaires",
celex:"02008R1333",
categorie:["Additifs","Étiquetage"],
statut:"V",
maj:"2023-07-20",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02008R1333-20230720"}],
resume:[
"Listes de l’Union; conditions d’utilisation par catégories d’aliments; exigences d’étiquetage."
],
exigences:[
"Vérifier matrices autorisées et doses max; pureté via 231/2012 (spécifications)."
],
audit:[ "Dossiers techniques additifs; attestations fournisseurs; revues formulations." ],
maj_points:[ "Mises à jour régulières des annexes." ]
},
{
id:"1334/2008",
titre:"Règlement (CE) n° 1334/2008 – Arômes",
celex:"02008R1334",
categorie:["Arômes","Étiquetage"],
statut:"V",
maj:"2023-03-21",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02008R1334-20230321"}],
resume:[
"Emploi d’arômes/ingrédients aromatisants; listes de substances autorisées."
],
exigences:[ "Conformité des arômes; étiquetage ‘arôme(s)’; restrictions spécifiques." ],
audit:[ "Spécifications fournisseurs; dosage/usage; mentions d’étiquetage." ],
maj_points:[ "Coordination avec 2065/2003 (arômes de fumée)." ]
},
{
id:"1924/2006",
titre:"Règlement (CE) n° 1924/2006 – Allégations nutritionnelles et de santé",
celex:"02006R1924",
categorie:["Allégations","Marketing"],
statut:"V",
maj:"2014-12-13",
liens:[
{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02006R1924-20141213"},
{label:"R (UE) 432/2012 – liste des allégations santé", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02012R0432-20210517"}
],
resume:[
"Cadre des allégations; autorisation/allégations santé listées; conditions d’emploi strictes."
],
exigences:[ "Preuves de conformité nutritionnelle; libellés exacts; pas de tromperie." ],
audit:[ "Revue supports (étiquette, web, PLV) vs listes autorisées." ],
maj_points:[ "Mises à jour des listes (432/2012)." ]
},
{
id:"396/2005",
titre:"Règlement (CE) n° 396/2005 – LMR pesticides",
celex:"02005R0396",
categorie:["Résidus","Pesticides"],
statut:"V",
maj:"2023-06-22",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005R0396-20230622"}],
resume:[
"LMR harmonisées; surveillance officielle; responsabilité exploitants."
],
exigences:[
"Plan de contrôle pesticides; sélection matières actives cibles; seuils LMR par produit."
],
audit:[ "Contrats fournisseurs; COA; actions en cas de dépassement LMR." ],
maj_points:[ "Mises à jour fréquentes des LMR (consulter la version récente)." ]
},
{
id:"589/2008",
titre:"Règlement (CE) n° 589/2008 – Normes de commercialisation œufs",
celex:"02008R0589",
categorie:["Marketing","Œufs"],
statut:"V",
maj:"2017-11-25",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02008R0589-20171125"}],
resume:[
"Marquage des œufs, catégories de qualité/poids, dates, traçabilité."
],
exigences:[ "Calibrage/qualité; informations au consommateur; marquage producteur." ],
audit:[ "Vérifier conformité marquage/étiquetage et registres." ],
maj_points:[ ]
},
{
id:"1379/2013",
titre:"Règlement (UE) n° 1379/2013 – Produits de la pêche/aquaculture (OCM)",
celex:"02013R1379",
categorie:["Marketing","Pêche"],
statut:"V",
maj:"2020-04-25",
liens:[{label:"EUR‑Lex (consolidé)", url:"https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:02013R1379-20200425"}],
resume:[ "Informations à fournir: espèce, zone de capture/production, méthode, etc." ],
exigences:[ "Étiquetage détaillé; traçabilité espèces/zone/méthode." ],
audit:[ "Vérifier cohérence espèces/FAO zone; documents fournisseurs." ],
maj_points:[ ]
}
];
/** =================== UI & Logic (Responsive) =================== **/
const sidebar = document.getElementById('sidebar');
const menu = document.getElementById('menu');
const themeFilter = document.getElementById('theme-filter');
const q = document.getElementById('q');
const title = document.getElementById('title');
const meta = document.getElementById('meta');
const contentWrapper = document.getElementById('content-wrapper');
const contentNavLinks = document.getElementById('content-nav-links');
const menuToggle = document.getElementById('menu-toggle');
const menuClose = document.getElementById('menu-close');
const overlay = document.getElementById('overlay');
const ICONS = {
resume: `<svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor"><path d="M2.5 3.5a.5.5 0 0 1 0-1h11a.5.5 0 0 1 0 1h-11Zm0 5a.5.5 0 0 1 0-1h11a.5.5 0 0 1 0 1h-11ZM2 11.5a.5.5 0 0 0 .5.5h6a.5.5 0 0 0 0-1h-6a.5.5 0 0 0-.5.5Z"/></svg>`,
exigences: `<svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor"><path d="M3.5 2A1.5 1.5 0 0 0 2 3.5v9A1.5 1.5 0 0 0 3.5 14h9a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 12.5 2h-9ZM9.03 8.32a.75.75 0 0 1-1.06 1.06L6.22 7.62a.75.75 0 0 1 0-1.06L7.97 4.81a.75.75 0 0 1 1.06 1.06L8.06 7l.97 1.32Z"/></svg>`,
refs: `<svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor"><path fill-rule="evenodd" d="M9.965 11.026a5 5 0 1 1 1.06-1.06l2.755 2.754a.75.75 0 1 1-1.06 1.06l-2.755-2.754ZM10.5 7a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Z" clip-rule="evenodd"/></svg>`
};
const TAGS = Array.from(new Set(DATA.flatMap(d => d.categorie))).sort();
let current = null;
let activeItemId = null;
function formatDate(iso) { if (!iso) return ""; const d = new Date(iso); return d.toLocaleDateString('fr-FR'); }
function renderThemeDropdown() {
themeFilter.innerHTML = '<option value="">Tous les thèmes</option>';
TAGS.forEach(tag => {
const option = document.createElement('option');
option.value = tag;
option.textContent = tag;
themeFilter.appendChild(option);
});
}
function match(text, query) {
return text.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase()
.includes(query.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase());
}
function renderMenu() {
const query = q.value.trim();
const activeTheme = themeFilter.value;
menu.innerHTML = "";
const list = DATA.filter(d => {
const byTheme = activeTheme ? d.categorie.includes(activeTheme) : true;
if (!byTheme) return false;
const byQuery = query ? match(d.id + " " + d.titre + " " + d.categorie.join(" "), query) : true;
return byQuery;
});
list.forEach(d => {
const item = document.createElement('a');
item.className = 'item' + (d.id === activeItemId ? ' active' : '');
item.onclick = () => select(d.id);
item.innerHTML = `
<div class="item-header">
<h4>${d.titre}</h4>
<code>${d.id}</code>
</div>
<div class="badges">
${d.categorie.slice(0, 3).map(c => `<span class="badge">${c}</span>`).join('')}
</div>
`;
menu.appendChild(item);
});
}
function select(id) {
activeItemId = id;
current = DATA.find(d => d.id === id);
if (!current) return;
title.textContent = current.titre;
meta.innerHTML = `
<span><b>Statut:</b> ${current.statut || 'V'}</span>
${current.maj ? `<span><b>MAJ:</b> ${formatDate(current.maj)}</span>` : ''}
`;
renderContent();
renderMenu();
contentWrapper.scrollTo({ top: 0, behavior: 'auto' });
// Close menu on selection if on mobile
if (window.innerWidth <= 1024) {
sidebar.classList.remove('open');
overlay.style.display = 'none';
}
}
function renderList(items) {
if (!items || !items.length) return '<p style="color:var(--text-light)"><em>— Non renseigné —</em></p>';
return '<ul>' + items.map(li => `<li>${li.replace(/'/g, '’')}</li>`).join('') + '</ul>';
}
function renderContent() {
if (!current) {
contentWrapper.innerHTML = `<div class="card"><p>Sélectionnez un texte dans la liste de gauche pour afficher ses détails.</p></div>`;
return;
}
contentWrapper.innerHTML = `
<section id="s-resume" class="content-section">
<h3>${ICONS.resume} Résumé & Portée</h3>
<div class="card"><h4>Résumé exécutif</h4>${renderList(current.resume)}</div>
<div class="card"><h4>Champ & Objectifs</h4>${renderList(current.scope || ["Champ d'application tel que défini dans le texte."])}</div>
<div class="card"><h4>Points Essentiels</h4>${renderList(current.key || ["Points de vigilance principaux."])}</div>
</section>
<section id="s-exigences" class="content-section">
<h3>${ICONS.exigences} Exigences & Audit</h3>
<div class="card"><h4>Exigences Clés</h4>${renderList(current.exigences)}</div>
<div class="card"><h4>Points d'Audit (type GFSI)</h4>${renderList(current.audit)}</div>
<div class="card"><h4>Valeurs / Aspects Techniques</h4>${renderList(current.limits || ["Consulter les annexes pour les valeurs limites (SML, LMR, etc.)."])}</div>
</section>
<section id="s-refs" class="content-section">
<h3>${ICONS.refs} Références & Mises à Jour</h3>
<div class="card">
<h4>Points de Vigilance</h4>${renderList(current.maj_points)}
</div>
<div class="card">
<h4>Liens Officiels</h4>
<div class="links">${(current.liens || []).map(l => `<a class="btn-link" target="_blank" rel="noopener" href="${l.url}">🔗 ${l.label}</a>`).join('')}</div>
</div>
</section>
`;
}
function initNavigation() {
contentNavLinks.addEventListener('click', (e) => {
e.preventDefault();
const targetLink = e.target.closest('a');
if (!targetLink) return;
contentNavLinks.querySelectorAll('a').forEach(link => link.classList.remove('active'));
targetLink.classList.add('active');
const targetId = targetLink.dataset.target;
const targetElement = document.getElementById(targetId);
if (targetElement) {
targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
}
function initMobileMenu() {
menuToggle.onclick = () => {
sidebar.classList.add('open');
overlay.style.display = 'block';
};
menuClose.onclick = () => {
sidebar.classList.remove('open');
overlay.style.display = 'none';
};
overlay.onclick = () => {
sidebar.classList.remove('open');
overlay.style.display = 'none';
};
}
function init() {
q.onkeyup = renderMenu;
themeFilter.onchange = renderMenu;
renderThemeDropdown();
renderMenu();
if (DATA[0]) {
select(DATA[0].id);
} else {
renderContent();
}
initNavigation();
initMobileMenu();
}
init();
</script>
</body>
</html>