#!/usr/bin/env python3
"""Generate PM_EL_T07_VOP_eLearning_v1.1.html"""

import datetime

OUT = "/root/projects/jg/2026-PM-eLearning/deliverables/PM_EL_T07_VOP_eLearning_v1.1.html"

modules = [
    {
        "id": 1, "title": "Wat is een VOP?",
        "content": """<p>Een Veilige Opstart Procedure (VOP) is een gestructureerde, stapsgewijze procedure die wordt gevolgd bij het <strong>opstarten van een installatie of proceslijn na een stilstand, onderhoud of modificatie</strong>. Het doel is om te garanderen dat de installatie veilig, volledig en gecontroleerd in bedrijf wordt gesteld.</p>
<p>Een VOP is verplicht bij Seveso-inrichtingen (BRZO 2015, art. 12) en bij installaties die vallen onder NTA 8620 (technische regelgeving voor procesveiligheid). Bij Phoenix Metals B.V. zijn beide van toepassing: we verwerken gevaarlijke stoffen (H₂SO₄, NaOH, V₂O₅) in een Seveso III-geclassificeerde inrichting.</p>
<p>Een VOP is géén routine-startprocedure. Het wordt specifiek ingezet na situaties waarbij de integriteit van de installatie mogelijk is aangetast: groot onderhoud, revisie, modificatie, of na een noodsituatie.</p>
<p>De MD (Stijn van Zelst) is de eindverantwoordelijke voor goedkeuring van elke VOP op PlantOne IJmuiden en Rotterdam.</p>""",
        "wistje": "De term VOP komt voort uit de procesveiligheid (Process Safety). Internationaal wordt vaak gesproken van 'Pre-Startup Safety Review' (PSSR), zoals gedefinieerd in OSHA 29 CFR 1910.119(i) en Seveso III-richtlijn art. 12.",
        "praktijk": "Bij Phoenix Metals is elke VOP gekoppeld aan een PtW (Permit to Work). Zonder geldig PtW wordt geen VOP gestart. Dit is vastgelegd in het Veiligheidsmanagement Systeem (VMS).",
        "vraag": "Wanneer is een VOP verplicht bij Phoenix Metals?",
        "opties": ["Bij elke dagelijkse start", "Alleen na een noodsituatie", "Na stilstand, onderhoud of modificatie van een Seveso-installatie", "Alleen op verzoek van de MD"],
        "correct": 2
    },
    {
        "id": 2, "title": "VOP vs normale procedure",
        "content": """<p>Het is cruciaal om het verschil te kennen tussen een <strong>normale startprocedure</strong> en een <strong>VOP</strong>. Een normale startprocedure wordt gebruikt bij routinegewijs opstarten (bijv. na een geplande pauze of shiftwissel) waarbij geen onderhoud of modificatie heeft plaatsgevonden.</p>
<p>Een VOP wordt ingezet wanneer de installatie is <strong>geopend, gewijzigd of hersteld</strong>. Denk aan: vervanging van een pomp, revisie van een reactor, aanpassing van een leiding of na een noodsituatie. In deze gevallen kan de integriteit van het systeem niet meer als vanzelfsprekend worden aangenomen.</p>
<p><strong>Risico's bij verkeerde keuze:</strong> Een VOP toepassen waar een normale procedure volstaat leidt tot onnodige vertraging. Een normale procedure toepassen waar een VOP vereist is, kan leiden tot het missen van kritieke controles — met alle risico's op lekkage, overdruk of chemische blootstelling.</p>
<p>De beslissing VOP of normaal ligt bij de procesingenieur en wordt bevestigd door de MD. Twijfel? Dan is een VOP altijd de veiligere keuze.</p>""",
        "wistje": "In de procesindustrie is >60% van de incidenten bij opstart gerelateerd aan het niet (volledig) uitvoeren van controles. Bron: Health and Safety Executive (HSE UK), 2023 rapport.",
        "praktijk": "Phoenix Metals hanteert een beslisboom (flowchart) die in de controlekamer hangt. Aan de hand van 5 vragen (is er onderhoud geweest? is het systeem geopend? etc.) bepaal je of een VOP vereist is.",
        "vraag": "Wat is het grootste risico van een NORMALE procedure toepassen waar een VOP vereist is?",
        "opties": ["Tijdverlies", "Missen van kritieke controles met risico op lekkage/overdruk", "Papierwerk", "Er is geen risico"],
        "correct": 1
    },
    {
        "id": 3, "title": "De 10-stappen VOP",
        "content": """<p>De VOP bij Phoenix Metals bestaat uit 10 vaste stappen die <strong>strikt in volgorde</strong> moeten worden doorlopen:</p>
<p><strong>Stap 1 — Veiligheidscheck:</strong> Verifieer dat alle LOTO (Lock-Out/Tag-Out) nog actief is en dat de werkplek schoon en veilig is.</p>
<p><strong>Stap 2 — LOTO verwijdering:</strong> LOTO wordt pas verwijderd nadat alle werk is afgerond en getekend. Verwijdering gebeurt door de persoon die de LOTO heeft geplaatst.</p>
<p><strong>Stap 3 — Visuele inspectie:</strong> Inspecteer de installatie op zichtbare gebreken: losse verbindingen, ontbrekende pakkingen, gereedschap in de installatie, lekkagesporen.</p>
<p><strong>Stap 4 — Functietest:</strong> Test het functioneren van kleppen, pompen, sensoren en veiligheidsvoorzieningen (noodstop, ontspanningskleppen).</p>
<p><strong>Stap 5 — Calibratie:</strong> Verifieer dat alle meetinstrumenten gecalibreerd zijn en binnen de specificaties vallen.</p>
<p><strong>Stap 6 — Communicatie:</strong> Informeer alle betrokkenen over de geplande opstart. Betreft: operatoren, onderhoud, laboratorium, HSE.</p>
<p><strong>Stap 7 — Vrijgave:</strong> De MD (of gemandateerde) tekent de vrijgave. Dit is het formele startsein.</p>
<p><strong>Stap 8 — Opstart:</strong> Breng de installatie stapsgewijs in bedrijf volgens het opstartprotocol. Monitor continu de parameters.</p>
<p><strong>Stap 9 — Monitoring:</strong> Volg de eerste uren na opstart extra kritiek. Controleer druk, temperatuur, debiet en lekkage elke 15 minuten.</p>
<p><strong>Stap 10 — Evaluatie:</strong> Na 24 uur wordt de opstart geëvalueerd. Bevindingen worden gedocumenteerd en zo nodig leidend tot aanpassingen.</p>""",
        "wistje": "De 10-stappen VOP is afgeleid van het COMAH (Control of Major Accident Hazards) framework en aangepast aan de specifieke risico's van vanadiumverwerking.",
        "praktijk": "De VOP-checklist van Phoenix Metals is digitaal beschikbaar in het VMS. Elke stap vereist een digitale handtekening van de verantwoordelijke. De checklist kan niet worden overgeslagen.",
        "vraag": "Wie mag LOTO verwijderen tijdens de VOP?",
        "opties": ["De shiftleider", "De persoon die de LOTO heeft geplaatst", "Iedereen met een PtW", "De MD"],
        "correct": 1
    },
    {
        "id": 4, "title": "Verificatiepunten reactor",
        "content": """<p>De reactor is het hart van de vanadiumverwerkingslijn. Bij opstart na onderhoud moeten de volgende verificatiepunten worden gecontroleerd:</p>
<p><strong>Druk:</strong> Controleer de ontspanningsklep (PRV) op correcte instelling. Verifieer de maximale werkdruk (MAWP) tegen het naamplaatje. Voer een hydraulische druktest uit indien de reactor is geopend geweest.</p>
<p><strong>Temperatuur:</strong> Controleer alle thermische wells en temperatuursensoren. Verifieer de alarmdrempels (hoog en laag). Test de temperatuur-trip functie.</p>
<p><strong>Lekkage:</strong> Voer een lekdichtheidscontrole uit met stikstof of lucht (afhankelijk van het systeem). Controleer alle flenzen, pakkingen en lasverbindingen op lekkage met een zeepoplossing of lekdetectiemiddel.</p>
<p><strong>Ventielen:</strong> Controleer de stand van alle inlaat-, uitlaat- en afsluiters. Verifieer de werking van regelventielen (CV waarde, slag-tijd). Test de noodafsluiter.</p>
<p><strong>Instrumenten:</strong> Kalibreer de niveaumeting (DP-cel), druktransmitters en flowmeters. Verifieer de communicatie met het DCS/SCADA systeem.</p>""",
        "wistje": "Een lekdichtheidscontrole met stikstof moet minimaal 30 minuten worden uitgevoerd op de testdruk (meestal 1,1 × MAWP) voordat deze als goedgekeurd kan worden beschouwd.",
        "praktijk": "Bij de reactor van PlantOne IJmuiden is elke flens genummerd. De VOP-checklist verwijst naar deze nummers. Per flens wordt de trekboutspanning en pakkingstoestand geverifieerd en vastgelegd.",
        "vraag": "Wat wordt als eerste gecontroleerd bij de reactor tijdens de VOP?",
        "opties": ["Temperatuur", "Druk en ontspanningsklep (PRV)", "Instrumenten", "Ventielen"],
        "correct": 1
    },
    {
        "id": 5, "title": "Verificatiepunten leidingen en pompen",
        "content": """<p>Leidingen en pompen vormen het transportsysteem van de installatie. Een fout hier leidt snel tot lekkage van H₂SO₄, NaOH of V₂O₅-bevattende stromen.</p>
<p><strong>Pakkingen:</strong> Controleer of alle pakkingen (gaskets) van het juiste type en materiaal zijn. Voor H₂SO₄-lijnen: PTFE-beklede pakkingen. Voor NaOH: EPDM of Butyl. Verkeerde pakking = gegarandeerde lekkage.</p>
<p><strong>Flenzen:</strong> Verifieer de trekboutspanning met een momentsleutel. Volg het kruislings aanspanprotocol. Controleer op zichtbare scheuren, corrosie of vervorming.</p>
<p><strong>Afdichtingen pompen:</strong> Controleer de mechanische afdichting (seal) op slijtage. Verifieer de spoeling (flush) van de seal. Test de lekdetectie bij de pomp.</p>
<p><strong>Stroomrichting:</strong> Verifieer de stroomrichting in elke leiding met behulp van stroomrichtingspijlen. Een omgekeerd geplaatste klep of niet-terugslagklep kan leiden tot waterhamer of terugstroming.</p>""",
        "wistje": "Waterhamer (surge) bij het opstarten van een pomp kan de druk tot 10× de nominale druk verhogen. Altijd langzaam de klep openen bij opstart — nooit abrupt.",
        "praktijk": "Phoenix Metals hanteert een 'flens-kaart': een overzicht van alle flenzen met het vereiste aanspanmoment per diameter en pakkingtype. Deze kaart is beschikbaar in de VOP-map.",
        "vraag": "Welk pakkingstype is vereist voor H₂SO₄-lijnen?",
        "opties": ["EPDM", "PTFE-beklede pakkingen", "Rubber", "Karton"],
        "correct": 1
    },
    {
        "id": 6, "title": "Verificatiepunten meetinstrumenten",
        "content": """<p>Meetinstrumenten zijn de ogen en oren van de installatie. Onjuiste of ongecalibreerde instrumenten geven een vals gevoel van veiligheid.</p>
<p><strong>Calibratie:</strong> Elk instrument moet vóór opstart gecalibreerd zijn. De kalibratiecertificaten moeten beschikbaar en binnen de geldigheidsduur zijn. Bij Phoenix Metals is de kalibratiecyclus: druk/temperatuur 12 maanden, flow 6 maanden, gasdetectie maandelijks.</p>
<p><strong>Nulpunt:</strong> Controleer het nulpunt (zero) van elke zender. Een verschuiving van het nulpunt leidt tot systematische meetfouten. Voer een zero-check uit met de referentie.</p>
<p><strong>Bereik:</strong> Verifieer dat het meetbereik (span) overeenkomt met de procescondities. Een druktransmitter met een bereik van 0-10 bar is nutteloos als het proces op 15 bar draait.</p>
<p><strong>Alarmdrempels:</strong> Controleer dat de alarmdrempels in het DCS overeenkomen met de ontwerpspecificaties. Test de alarmfunctie door een simulatie uit te voeren. Verifieer zowel de hoge als de lage alarmen.</p>""",
        "wistje": "Een kalibratiecertificaat heeft een beperkte geldigheid. Een verlopen certificaat betekent dat het instrument buiten kalibratie is en niet gebruikt mag worden voor veiligheidskritische metingen.",
        "praktijk": "Phoenix Metals heeft een digitaal kalibratiemanagement systeem. Bij elke VOP genereert het systeem automatisch een lijst van instrumenten die moeten worden gecontroleerd, inclusief de laatste kalibratiedatum.",
        "vraag": "Wat is de kalibratiecyclus voor gasdetectie-instrumenten bij Phoenix Metals?",
        "opties": ["12 maanden", "6 maanden", "Maandelijks", "Elke 3 maanden"],
        "correct": 2
    },
    {
        "id": 7, "title": "Rollen en bevoegdheden",
        "content": """<p>Bij een VOP zijn drie rollen duidelijk gedefinieerd, elk met eigen bevoegdheden en verantwoordelijkheden:</p>
<p><strong>Uitvoerder:</strong> De operator of technicus die de fysieke controles en handelingen uitvoert. De uitvoerder doorloopt de VOP-checklist stap voor stap, voert de metingen uit en tekent voor voltooiing van elke stap. Bevoegdheid: uitvoeren van controles en het signaleren van afwijkingen.</p>
<p><strong>Controleur:</strong> Een tweede persoon (vaak de shiftleider of een collega-operator) die de controles van de uitvoerder onafhankelijk verifieert. De controleur tekent voor goedkeuring van elke stap. Dit is het <strong>four-eyes principle</strong>. Bevoegdheid: goedkeuren of afkeuren van uitgevoerde controles.</p>
<p><strong>Goedkeurder:</strong> De MD (Stijn van Zelst) of een door hem gemandateerde persoon. De goedkeurder geeft de uiteindelijke vrijgave voor opstart (VOP stap 7). Bevoegdheid: eindgoedekeuring, stoppen van de VOP bij onvoldoende vertrouwen, en mandateren van derden.</p>
<p>Geen van deze rollen mag door één persoon worden gecombineerd. Scheiding van taken is een harde eis.</p>""",
        "wistje": "Het four-eyes principle is niet alleen een best practice maar een wettelijke eis onder BRZO 2015 (art. 12.3) voor veiligheidskritische handelingen bij Seveso-inrichtingen.",
        "praktijk": "Bij Phoenix Metals wordt de VOP-rollenverdeling digitaal vastgelegd in het VMS. Het systeem accepteert niet dat uitvoerder en controleur dezelfde persoon zijn — dubbele handtekening wordt geblokkeerd.",
        "vraag": "Welk principe wordt toegepast bij de rolverdeling in de VOP?",
        "opties": ["Three-eyes principle", "Four-eyes principle", "Single-responsibility", "Self-check"],
        "correct": 1
    },
    {
        "id": 8, "title": "Communicatie-protocol bij opstart",
        "content": """<p>Goede communicatie is de ruggengraat van een veilige opstart. Het communicatie-protocol bij Phoenix Metals definieert wie, wat, wanneer en hoe communiceert.</p>
<p><strong>Wie informeert wie:</strong> De uitvoerder informeert de controleur na elke voltooide stap. De controleur informeert de shiftleider na voltooiing van de verificatie. De shiftleider informeert de MD bij afwijkingen en bij de aanvraag voor vrijgave. De MD informeert de plantmanager en HSE bij de vrijgave.</p>
<p><strong>Checklist communicatie:</strong> Vóór de opstart wordt een communicatie-checklist doorlopen: 1) Alle operatoren geïnformeerd? 2) Onderhoudspersoneel buiten de installatie? 3) Laboratorium op de hoogte (monsternames)? 4) HSE geïnformeerd? 5) Externe aannemers geïnformeerd?</p>
<p><strong>PtW-koppeling:</strong> De VOP is gekoppeld aan het Permit to Work (PtW) systeem. Het PtW moet worden afgesloten (close-out) voordat de VOP start. Openstaande PtW's blokkeren de VOP.</p>
<p>Bij afwijkingen of noodsituaties tijdens de opstart: direct STOP, informeer de shiftleider, en wacht op instructies. De installatie wordt in een veilige staat gebracht (safe state).</p>""",
        "wistje": "Onderzoek toont aan dat communicatiefouten bijdragen aan >70% van de incidenten tijdens opstart- en afregelfasen. Duidelijke protocollen reduceren dit risico significant.",
        "praktijk": "Phoenix Metals gebruikt een vaste walkie-talkie op het opstartkanaal. Tijdens een VOP is dit kanaal exclusief gereserveerd — geen privé-gesprekken. De shiftleider heeft de lead.",
        "vraag": "Wat blokkeert de start van een VOP?",
        "opties": ["Een kale vloer", "Openstaande PtW's (Permit to Work)", "Regen", "Te veel personeel"],
        "correct": 1
    },
    {
        "id": 9, "title": "Veelgemaakte fouten — Top 5",
        "content": """<p>Uit incidentanalyses in de procesindustrie zijn de volgende top-5 fouten bij opstartprocedures geïdentificeerd:</p>
<p><strong>1. Te snel opstarten.</strong> De druk om productie te hervatten leidt ertoe dat controles worden overgeslagen of gehaast. Neem de tijd — elke stap bestaat om een reden. Bij Phoenix Metals is de MD de enige die een versnelde VOP kan goedkeuren, en alleen met gemotiveerde argumenten.</p>
<p><strong>2. Checklist niet volledig uitvoeren.</strong> Het 'vink-mentaliteit' probleem: men vinkt aan zonder daadwerkelijk te controleren. Oplossing: het four-eyes principle en de eis om meetwaarden op te schrijven, niet alleen aan te vinken.</p>
<p><strong>3. Geen communicatie.</strong> Operatoren starten op zonder alle betrokkenen te informeren. Gevolg: iemand bevindt zich onverwacht in de installatie of een aannemer voert nog werk uit. Altijd de communicatie-checklist doorlopen.</p>
<p><strong>4. Instrumenten niet gecalibreerd.</strong> Vertrouwen op onbetrouwbare meetsignalen leidt tot verkeerde beslissingen. Controleer altijd de kalibratiestatus vóór opstart.</p>
<p><strong>5. LOTO te vroeg verwijderd.</strong> LOTO wordt verwijderd voordat alle werk is afgerond en afgetekend. Gevolg: de installatie wordt onbedoeld onder spanning gezet terwijl er nog iemand aan het werk is.</p>""",
        "wistje": "De Piper Alpha ramp (1988, 167 doden) was deels te wijten aan een onvolledige Permit to Work procedure en gebrekkige communicatie bij opstart. Dit incident was de aanleiding voor veel huidige veiligheidsvoorschriften.",
        "praktijk": "Phoenix Metals analyseert na elke VOP de bevindingen in een lessons-learned sessie. Terugkerende fouten worden vertaald naar verbeteracties in het VMS en meegenomen in de volgende training.",
        "vraag": "Wat is de meest voorkomende oorzaak van incidenten bij opstart?",
        "opties": ["Materieelfalen", "Te snel opstarten / controles overslaan", "Weeromstandigheden", "Softwarefouten"],
        "correct": 1
    },
    {
        "id": 10, "title": "Phoenix Metals specifiek: opstart vanadiumverwerkingslijn",
        "content": """<p>De opstart van de vanadiumverwerkingslijn bij Phoenix Metals vereist specifieke aandachtspunten die verder gaan dan de algemene VOP:</p>
<p><strong>Documentatie:</strong> Verzamel vóór opstart: P&ID's (bijgewerkt na modificatie), veiligheidsinformatiebladen (SDS) van V₂O₅, H₂SO₄, NaOH en Al₂(SO₄)₃, de HAZOP-rapportage, SIL-classificatie van veiligheidsfuncties, en de as-built documentatie van eventuele wijzigingen.</p>
<p><strong>Specifieke controles:</strong> 1) Verifieer de H₂SO₄-dosering: is de concentratie correct (typisch 98%) en is de lijn lekvrij? 2) Controleer de NaOH-wasinstallatie: is de wasvloeistof vers en op sterkte? 3) Verifieer de stofafzuiging bij de V₂O₅-handling: filters schoon, debiet correct? 4) Controleer de neutraalisatie-eenheid: pH-bereik, alarmdrempels, afvoer.</p>
<p><strong>Registratie:</strong> Alle VOP-gegevens worden geregistreerd in het VMS: datum/tijd, betrokkenen, checklist-resultaten, afwijkingen en acties. De registratie is vereist voor de BRZO-rapportage en kan tijdens een inspectie door het bevoegd gezag worden opgevraagd.</p>
<p>Na een succesvolle opstart volgt een monitoringperiode van minimaal 24 uur met verhoogde aandacht voor druk, temperatuur, lekkage en emissies. De MD tekent de evaluatie af.</p>""",
        "wistje": "V₂O₅ is geclassificeerd als H351 (verdacht van kankerverwekkendheid) en H372 (schadelijk bij langdurige blootstelling via inhalatie). De opstartprocedure moet garanderen dat stofemissie tot een minimum wordt beperkt.",
        "praktijk": "Bij Phoenix Metals wordt na elke opstart van de vanadiumlijn een luchtmeetpunt bemonsterd (stationaire meetuitrusting). De resultaten worden automatisch vergeleken met de wettelijke grenswaarden en geregistreerd in het milieumanagement systeem.",
        "vraag": "Wat is een specifieke controle bij opstart van de vanadiumverwerkingslijn?",
        "opties": ["Koffieapparaat controleren", "Stofafzuiging bij V₂O₅-handling verifiëren", "Parkeerplaats inspecteren", "Wifi-netwerk testen"],
        "correct": 1
    }
]

quiz = [
    {"v": "Wanneer is een VOP verplicht bij Phoenix Metals?", "o": ["Elke dagelijkse start", "Alleen na nood", "Na stilstand/onderhoud/modificatie van Seveso-installatie", "Op verzoek MD"], "c": 2},
    {"v": "Wat is het grootste risico van een normale procedure i.p.v. VOP?", "o": ["Tijdverlies", "Missen van kritieke controles", "Papierwerk", "Geen risico"], "c": 1},
    {"v": "Wie mag LOTO verwijderen tijdens de VOP?", "o": ["Shiftleider", "Degene die LOTO plaatste", "Iedereen met PtW", "MD"], "c": 1},
    {"v": "Welk pakkingtype voor H₂SO₄-lijnen?", "o": ["EPDM", "PTFE-bekleed", "Rubber", "Karton"], "c": 1},
    {"v": "Kalibratiecyclus gasdetectie bij Phoenix Metals?", "o": ["12 maanden", "6 maanden", "Maandelijks", "3 maanden"], "c": 2},
    {"v": "Welk principe bij VOP-rollenverdeling?", "o": ["Three-eyes", "Four-eyes principle", "Single-responsibility", "Self-check"], "c": 1},
    {"v": "Wat blokkeert de VOP-start?", "o": ["Kale vloer", "Openstaande PtW's", "Regen", "Te veel personeel"], "c": 1},
    {"v": "Meest voorkomende oorzaak incidenten bij opstart?", "o": ["Materieelfalen", "Te snel opstarten / controles overslaan", "Weer", "Software"], "c": 1},
    {"v": "Specifieke controle bij opstart vanadiumlijn?", "o": ["Koffieapparaat", "Stofafzuiging V₂O₅-handling", "Parkeerplaats", "Wifi"], "c": 1},
    {"v": "Hoe lang duurt de monitoringperiode na opstart bij Phoenix Metals?", "o": ["1 uur", "4 uur", "Minimaal 24 uur", "1 week"], "c": 2}
]

def build():
    today = datetime.date.today().strftime("%d-%m-%Y")
    mods_html = ""
    for m in modules:
        opts = "".join(f'<label class="quiz-option" onclick="checkModuleQ(this,{m['id']},{i},{m['correct']})"><input type="radio" name="mq{m['id']}">{o}</label>' for i, o in enumerate(m["opties"]))
        mods_html += f"""
    <div class="module" id="mod{m['id']}" style="display:none">
      <h2>Module {m['id']}: {m['title']}</h2>
      {m['content']}
      <div class="wistje" onclick="this.classList.toggle('open')"><strong>📖 Wist je dat?</strong><div class="wistje-body">{m['wistje']}</div></div>
      <div class="praktijk"><strong>🏭 Phoenix Metals Praktijk</strong><p>{m['praktijk']}</p></div>
      <div class="controle-vraag">
        <h3>✅ Controle-vraag</h3>
        <p>{m['vraag']}</p>
        {opts}
        <div id="mq{m['id']}fb" class="feedback"></div>
      </div>
      <div class="nav-buttons">
        {'<button onclick="goMod(' + str(m['id']-1) + ')">⬅ Vorige</button>' if m['id'] > 1 else ''}
        <button onclick="goMod({m['id']+1 if m['id'] < 10 else 'quiz'})">{'Volgende module ➡' if m['id'] < 10 else 'Start Quiz 📋'}</button>
      </div>
    </div>"""

    quiz_html = ""
    for i, q in enumerate(quiz):
        opts = "".join(f'<label class="quiz-option" onclick="checkQuiz(this,{i},{j},{q['c']})"><input type="radio" name="q{i}">{o}</label>' for j, o in enumerate(q["o"]))
        quiz_html += f"""
      <div class="quiz-q" id="qq{i}">
        <p><strong>Vraag {i+1}:</strong> {q['v']}</p>
        {opts}
        <div id="qfb{i}" class="feedback"></div>
      </div>"""

    html = """<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>T07 — VOP Veilige Opstart Procedure | Phoenix Metals B.V.</title>
<style>
*{{margin:0;padding:0;box-sizing:border-box}}
body{{font-family:Calibri,Arial,sans-serif;background:#e8f4f8;color:#1F2937;line-height:1.6}}
.header{{background:linear-gradient(135deg,#003366,#1a5276);color:#fff;padding:20px 30px;position:sticky;top:0;z-index:100;box-shadow:0 2px 10px rgba(0,0,0,.3)}}
.header h1{{font-size:1.3em}}.header .sub{{font-size:.85em;opacity:.85}}
.progress-bar{{height:6px;background:#e8f4f8;border-radius:3px;overflow:hidden;margin-top:8px}}
.progress-bar .fill{{height:100%;background:linear-gradient(90deg,#f39c12,#27ae60);transition:width .4s;width:0%}}
.container{{max-width:900px;margin:20px auto;padding:0 15px}}
.module,.welcome,.quiz-section,.cert-section{{background:#fff;border-radius:12px;padding:25px 30px;margin-bottom:20px;box-shadow:0 2px 12px rgba(0,0,0,.08)}}
h2{{color:#003366;margin-bottom:12px}}h3{{color:#1a5276;margin:12px 0 8px}}
p{{margin-bottom:10px}}
.wistje{{background:#fff8e1;border-left:4px solid #f39c12;padding:10px 15px;margin:15px 0;cursor:pointer;border-radius:0 8px 8px 0}}
.wistje .wistje-body{{display:none;margin-top:8px}}.wistje.open .wistje-body{{display:block}}
.praktijk{{background:#e8f4f8;border-left:4px solid #003366;padding:12px 15px;margin:15px 0;border-radius:0 8px 8px 0}}
.praktijk strong{{color:#003366}}
.controle-vraag{{background:#f0f9ff;border:2px solid #1a5276;border-radius:8px;padding:15px;margin:15px 0}}
.quiz-option{{display:block;padding:10px 15px;margin:5px 0;border:2px solid #e5e7eb;border-radius:8px;cursor:pointer;transition:all .2s}}
.quiz-option:hover{{background:#e8f4f8;border-color:#1a5276}}
.quiz-option.correct{{background:#d5f5e3;border-color:#27ae60}}
.quiz-option.wrong{{background:#fadbd8;border-color:#e74c3c}}
.feedback{{margin-top:8px;font-weight:bold;min-height:1.2em}}
.nav-buttons{{display:flex;justify-content:space-between;margin-top:20px}}
button{{background:linear-gradient(135deg,#003366,#1a5276);color:#fff;border:none;padding:12px 24px;border-radius:8px;cursor:pointer;font-size:1em;transition:all .2s}}
button:hover{{transform:translateY(-2px);box-shadow:0 4px 12px rgba(0,51,102,.4)}}
.btn-quiz{{background:linear-gradient(135deg,#f39c12,#e67e22)}}
.quiz-result{{text-align:center;padding:20px}}
.cert-section{{text-align:center}}
.cert-box{{border:3px solid #003366;border-radius:12px;padding:30px;margin:20px auto;max-width:600px;background:linear-gradient(135deg,#fff,#e8f4f8)}}
.cert-box h2{{color:#003366;font-size:1.5em}}
.hidden{{display:none!important}}
@media(max-width:600px){{.container{{padding:0 8px}}.module,.welcome,.quiz-section,.cert-section{{padding:15px}}}}
</style>
</head>
<body>
<div class="header">
  <h1>🔄 T07 — VOP: Veilige Opstart Procedure</h1>
  <div class="sub">Phoenix Metals B.V. | PlantOne IJmuiden &amp; Rotterdam | eLearning v1.1</div>
  <div class="progress-bar"><div class="fill" id="pbar"></div></div>
</div>
<div class="container">

  <div class="welcome" id="welcome">
    <h2>Welkom bij deze eLearning</h2>
    <p>Deze training behandelt de Veilige Opstart Procedure (VOP) bij Phoenix Metals B.V. Na het doorlopen van 10 modules volgt een quiz. Je hebt minimaal 80% correct nodig om te slagen.</p>
    <p><strong>Structuur:</strong> 10 modules → Quiz (10 vragen) → Certificaat</p>
    <p><strong>Verantwoordelijke:</strong> MD Stijn van Zelst | <strong>Locatie:</strong> PlantOne IJmuiden + Rotterdam</p>
    <div style="text-align:center;margin-top:20px"><button onclick="goMod(1)">Start Training ➡</button></div>
  </div>

  {mods_html}

  <div class="quiz-section" id="quiz" style="display:none">
    <h2>📋 Quiz — Veilige Opstart Procedure</h2>
    <p>Beantwoord alle 10 vragen. Je hebt minimaal 8 correct nodig (80%).</p>
    {quiz_html}
    <div style="text-align:center;margin-top:20px">
      <button class="btn-quiz" onclick="submitQuiz()">Inleveren ✅</button>
    </div>
    <div id="quiz-result" class="quiz-result hidden">
      <h3 id="result-title"></h3>
      <p id="result-text"></p>
      <div id="cert-input" class="hidden">
        <p>Vul je naam in voor het certificaat:</p>
        <input type="text" id="uname" placeholder="Voor- en achternaam" style="padding:8px;font-size:1em;border:2px solid #003366;border-radius:6px;width:280px;margin:10px">
        <button onclick="showCert()">Genereer Certificaat 🎓</button>
      </div>
    </div>
  </div>

  <div class="cert-section hidden" id="cert">
    <div class="cert-box">
      <h2>🎓 Certificaat van Voltooiing</h2>
      <p style="font-size:1.2em;margin:15px 0">Dit certificaat wordt verstrekt aan</p>
      <h3 id="cert-name" style="font-size:1.4em;color:#003366"></h3>
      <p>voor het succesvol voltooien van</p>
      <p><strong>T07 — VOP: Veilige Opstart Procedure</strong></p>
      <p>Phoenix Metals B.V. — PlantOne IJmuiden &amp; Rotterdam</p>
      <p id="cert-score" style="margin-top:10px"></p>
      <p id="cert-date" style="margin-top:10px;color:#666"></p>
      <p style="margin-top:15px;font-size:.9em;color:#666">MD: Stijn van Zelst | Versie 1.1 | """ + today + """</p>
    </div>
    <button onclick="window.print()" style="margin-top:15px">🖨️ Afdrukken</button>
  </div>

</div>
<script>
const total=10;let current=0,score=0,answered={},quizAnswered={};
function goMod(n){{
  document.querySelectorAll('.module,.welcome,.quiz-section,.cert-section').forEach(e=>e.style.display='none');
  if(n==='quiz'){{document.getElementById('quiz').style.display='block';current=total;}}
  else if(n==='cert'){{document.getElementById('cert').classList.remove('hidden');document.getElementById('cert').style.display='block';current=total+1;}}
  else{{document.getElementById('mod'+n).style.display='block';current=n-1;}}
  document.getElementById('pbar').style.width=((current)/(total+1)*100)+'%';
  window.scrollTo(0,0);
}}
function checkModuleQ(el,mod,idx,correct){{
  if(answered[mod])return;answered[mod]=true;
  el.parentElement.querySelectorAll('.quiz-option').forEach((o,i)=>{{
    o.style.pointerEvents='none';
    if(i===correct)o.classList.add('correct');
    if(i===idx&&i!==correct)o.classList.add('wrong');
  }});
  let fb=document.getElementById('mq'+mod+'fb');
  fb.textContent=idx===correct?'✅ Correct!':'❌ Fout — het juiste antwoord is gemarkeerd.';
  fb.style.color=idx===correct?'#27ae60':'#e74c3c';
}}
function checkQuiz(el,qi,idx,correct){{
  if(quizAnswered[qi]!==undefined)return;quizAnswered[qi]=idx;
  el.parentElement.querySelectorAll('.quiz-option').forEach((o,i)=>{{
    o.style.pointerEvents='none';
    if(i===correct)o.classList.add('correct');
    if(i===idx&&i!==correct)o.classList.add('wrong');
  }});
  let fb=document.getElementById('qfb'+qi);
  fb.textContent=idx===correct?'✅ Correct!':'❌ Fout';
  fb.style.color=idx===correct?'#27ae60':'#e74c3c';
}}
function submitQuiz(){{
  if(Object.keys(quizAnswered).length<total){{alert('Beantwoord alle 10 vragen eerst!');return;}}
  score=0;
  const answers={0:2,1:1,2:1,3:1,4:2,5:1,6:1,7:1,8:1,9:2};
  for(let k in quizAnswered)if(quizAnswered[k]===answers[k])score++;
  let ok=score>=8;
  document.getElementById('result-title').textContent=ok?'🎉 Gefeliciteerd — Geslaagd!':'❌ Helaas — Niet geslaagd';
  document.getElementById('result-title').style.color=ok?'#27ae60':'#e74c3c';
  document.getElementById('result-text').textContent='Score: '+score+'/10 ('+(score*10)+'%) — Cesuur: 80%';
  document.getElementById('quiz-result').classList.remove('hidden');
  if(ok)document.getElementById('cert-input').classList.remove('hidden');
  document.getElementById('pbar').style.width='95%';
}}
function showCert(){{
  let name=document.getElementById('uname').value.trim();
  if(!name){{alert('Vul je naam in!');return;}}
  document.getElementById('cert-name').textContent=name;
  document.getElementById('cert-score').textContent='Behaald resultaat: '+score+'/10 ('+(score*10)+'%)';
  document.getElementById('cert-date').textContent='Datum: '+new Date().toLocaleDateString('nl-NL');
  goMod('cert');
}}
</script>
</body>
</html>"""

    with open(OUT, "w", encoding="utf-8") as f:
        f.write(html)
    print(f"✅ {OUT}")

if __name__ == "__main__":
    build()
