#!/usr/bin/env python3
"""
Generate all 7 PPTX presentations for T01-T07.
Golden Standard: 35+ slides, professional layout, JvG branding.
"""
import os
from pptx import Presentation
from pptx.util import Inches, Pt, Cm, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE
import copy

# Colors
PRIMARY = RGBColor(0x00, 0x33, 0x66)
DARK_TEXT = RGBColor(0x1F, 0x29, 0x37)
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
LIGHT_BG = RGBColor(0xE5, 0xE7, 0xEB)
ACCENT = RGBColor(0xF3, 0x9C, 0x12)
RED = RGBColor(0xE7, 0x4C, 0x3C)
GREEN = RGBColor(0x27, 0xAE, 0x60)
HEADER_BG = RGBColor(0x00, 0x33, 0x66)

SLIDE_WIDTH = Inches(13.333)
SLIDE_HEIGHT = Inches(7.5)

OUTPUT_DIR = "/root/projects/jg/2026-PM-eLearning/deliverables"

def create_prs():
    prs = Presentation()
    prs.slide_width = SLIDE_WIDTH
    prs.slide_height = SLIDE_HEIGHT
    return prs

def add_headerBar(slide, title_text, subtitle_text=None):
    """Add dark blue header bar with title"""
    # Header bar
    shape = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, SLIDE_WIDTH, Inches(1.2))
    shape.fill.solid()
    shape.fill.fore_color.rgb = PRIMARY
    shape.line.fill.background()
    
    # Title
    txBox = slide.shapes.add_textbox(Inches(0.5), Inches(0.15), Inches(10), Inches(0.9))
    tf = txBox.text_frame
    tf.word_wrap = True
    p = tf.paragraphs[0]
    p.text = title_text
    p.font.size = Pt(28)
    p.font.bold = True
    p.font.color.rgb = WHITE
    p.font.name = "Calibri"
    
    if subtitle_text:
        p2 = tf.add_paragraph()
        p2.text = subtitle_text
        p2.font.size = Pt(14)
        p2.font.color.rgb = RGBColor(0xBB, 0xCC, 0xDD)
        p2.font.name = "Calibri"
    
    # Footer
    footer = slide.shapes.add_textbox(Inches(0.5), Inches(6.9), Inches(10), Inches(0.4))
    tf2 = footer.text_frame
    p3 = tf2.paragraphs[0]
    p3.text = "JvG Consultancy | Safety • Governance • Advisory | © 2026"
    p3.font.size = Pt(8)
    p3.font.color.rgb = RGBColor(0x99, 0x99, 0x99)
    p3.font.name = "Calibri"
    
    return txBox

def add_icon_box(slide, icon, left, top, width=Inches(1), height=Inches(1)):
    """Add a large icon in a colored circle"""
    shape = slide.shapes.add_shape(MSO_SHAPE.OVAL, left, top, width, height)
    shape.fill.solid()
    shape.fill.fore_color.rgb = RGBColor(0xE8, 0xF4, 0xF8)
    shape.line.fill.background()
    tf = shape.text_frame
    tf.word_wrap = False
    p = tf.paragraphs[0]
    p.text = icon
    p.font.size = Pt(36)
    p.alignment = PP_ALIGN.CENTER
    tf.paragraphs[0].space_before = Pt(0)

def add_bullet_slide(slide, title, bullets, icon=None, subtitle=None):
    """Standard content slide with bullets"""
    add_headerBar(slide, title, subtitle)
    
    top = Inches(1.5)
    if icon:
        add_icon_box(slide, icon, Inches(11.5), Inches(1.5))
    
    txBox = slide.shapes.add_textbox(Inches(0.7), top, Inches(11), Inches(5))
    tf = txBox.text_frame
    tf.word_wrap = True
    
    for i, bullet in enumerate(bullets):
        if i == 0:
            p = tf.paragraphs[0]
        else:
            p = tf.add_paragraph()
        p.text = bullet
        p.font.size = Pt(18)
        p.font.color.rgb = DARK_TEXT
        p.font.name = "Calibri"
        p.space_after = Pt(8)
        p.level = 0
        # Add bullet character
        if not bullet.startswith("⚠️") and not bullet.startswith("✅") and not bullet.startswith("❌") and not bullet.startswith("🔥") and not bullet.startswith("☠️") and not bullet.startswith("🛡️") and not bullet.startswith("📋") and not bullet.startswith("🔧") and not bullet.startswith("🏭") and not bullet.startswith("💀") and not bullet.startswith("→"):
            p.text = "• " + bullet

def add_table_slide(slide, title, headers, rows, subtitle=None):
    """Slide with a professional table"""
    add_headerBar(slide, title, subtitle)
    
    num_cols = len(headers)
    num_rows = len(rows) + 1
    
    left = Inches(0.5)
    top = Inches(1.5)
    width = Inches(12.3)
    height = Inches(5)
    
    table_shape = slide.shapes.add_table(num_rows, num_cols, left, top, width, height)
    table = table_shape.table
    
    # Header row
    for j, h in enumerate(headers):
        cell = table.cell(0, j)
        cell.text = h
        for p in cell.text_frame.paragraphs:
            p.font.size = Pt(14)
            p.font.bold = True
            p.font.color.rgb = WHITE
            p.font.name = "Calibri"
            p.alignment = PP_ALIGN.CENTER
        cell.fill.solid()
        cell.fill.fore_color.rgb = PRIMARY
    
    # Data rows
    for i, row in enumerate(rows):
        for j, val in enumerate(row):
            cell = table.cell(i + 1, j)
            cell.text = str(val)
            for p in cell.text_frame.paragraphs:
                p.font.size = Pt(12)
                p.font.color.rgb = DARK_TEXT
                p.font.name = "Calibri"
            cell.fill.solid()
            cell.fill.fore_color.rgb = LIGHT_BG if i % 2 == 0 else WHITE
    
    return table

def add_two_column_slide(slide, title, left_title, left_items, right_title, right_items, subtitle=None):
    """Two-column layout"""
    add_headerBar(slide, title, subtitle)
    
    # Left box
    left_box = slide.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, Inches(0.5), Inches(1.5), Inches(5.8), Inches(5))
    left_box.fill.solid()
    left_box.fill.fore_color.rgb = RGBColor(0xE8, 0xF4, 0xF8)
    left_box.line.color.rgb = RGBColor(0x00, 0x33, 0x66)
    
    tf = left_box.text_frame
    tf.word_wrap = True
    p = tf.paragraphs[0]
    p.text = left_title
    p.font.size = Pt(18)
    p.font.bold = True
    p.font.color.rgb = PRIMARY
    p.font.name = "Calibri"
    
    for item in left_items:
        p = tf.add_paragraph()
        p.text = "• " + item
        p.font.size = Pt(14)
        p.font.color.rgb = DARK_TEXT
        p.font.name = "Calibri"
        p.space_after = Pt(4)
    
    # Right box
    right_box = slide.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, Inches(7), Inches(1.5), Inches(5.8), Inches(5))
    right_box.fill.solid()
    right_box.fill.fore_color.rgb = RGBColor(0xFD, 0xF2, 0xE9)
    right_box.line.color.rgb = ACCENT
    
    tf2 = right_box.text_frame
    tf2.word_wrap = True
    p2 = tf2.paragraphs[0]
    p2.text = right_title
    p2.font.size = Pt(18)
    p2.font.bold = True
    p2.font.color.rgb = RGBColor(0xD3, 0x54, 0x00)
    p2.font.name = "Calibri"
    
    for item in right_items:
        p2 = tf2.add_paragraph()
        p2.text = "• " + item
        p2.font.size = Pt(14)
        p2.font.color.rgb = DARK_TEXT
        p2.font.name = "Calibri"
        p2.space_after = Pt(4)

def add_flowchart_slide(slide, title, steps, subtitle=None):
    """Simple horizontal flowchart with boxes and arrows"""
    add_headerBar(slide, title, subtitle)
    
    n = len(steps)
    box_width = Inches(min(2.0, 11.0 / n))
    box_height = Inches(1.2)
    spacing = (Inches(12) - n * box_width) / max(n - 1, 1) if n > 1 else Inches(0)
    start_left = Inches(0.5)
    top = Inches(2.5)
    
    for i, step in enumerate(steps):
        left = int(start_left + i * (box_width + spacing))
        
        shape = slide.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, left, top, box_width, box_height)
        shape.fill.solid()
        shape.fill.fore_color.rgb = PRIMARY if i % 2 == 0 else RGBColor(0x1A, 0x52, 0x76)
        shape.line.fill.background()
        
        tf = shape.text_frame
        tf.word_wrap = True
        p = tf.paragraphs[0]
        p.text = step
        p.font.size = Pt(11)
        p.font.color.rgb = WHITE
        p.font.name = "Calibri"
        p.alignment = PP_ALIGN.CENTER
        tf.paragraphs[0].space_before = Pt(8)
        
        # Arrow between boxes
        if i < n - 1:
            arrow_left = int(left + box_width)
            arrow = slide.shapes.add_shape(MSO_SHAPE.RIGHT_ARROW, arrow_left, top + Inches(0.4), spacing, Inches(0.4))
            arrow.fill.solid()
            arrow.fill.fore_color.rgb = ACCENT
            arrow.line.fill.background()

def add_cover_slide(slide, title, subtitle, training_code):
    """Professional cover slide"""
    # Full dark background
    bg = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, SLIDE_WIDTH, SLIDE_HEIGHT)
    bg.fill.solid()
    bg.fill.fore_color.rgb = PRIMARY
    bg.line.fill.background()
    
    # Accent bar
    bar = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, Inches(0.5), Inches(3.2), Inches(2), Inches(0.06))
    bar.fill.solid()
    bar.fill.fore_color.rgb = ACCENT
    bar.line.fill.background()
    
    # Title
    txBox = slide.shapes.add_textbox(Inches(0.5), Inches(1.5), Inches(12), Inches(1.5))
    tf = txBox.text_frame
    p = tf.paragraphs[0]
    p.text = title
    p.font.size = Pt(40)
    p.font.bold = True
    p.font.color.rgb = WHITE
    p.font.name = "Calibri"
    
    # Subtitle
    txBox2 = slide.shapes.add_textbox(Inches(0.5), Inches(3.5), Inches(12), Inches(2))
    tf2 = txBox2.text_frame
    p2 = tf2.paragraphs[0]
    p2.text = subtitle
    p2.font.size = Pt(20)
    p2.font.color.rgb = RGBColor(0xBB, 0xCC, 0xDD)
    p2.font.name = "Calibri"
    
    p3 = tf2.add_paragraph()
    p3.text = training_code
    p3.font.size = Pt(16)
    p3.font.color.rgb = ACCENT
    p3.font.name = "Calibri"
    
    # Footer
    txBox3 = slide.shapes.add_textbox(Inches(0.5), Inches(6.2), Inches(12), Inches(0.5))
    tf3 = txBox3.text_frame
    p4 = tf3.paragraphs[0]
    p4.text = "Phoenix Metals B.V. | PlantOne IJmuiden & Rotterdam"
    p4.font.size = Pt(14)
    p4.font.color.rgb = RGBColor(0x88, 0x99, 0xAA)
    p4.font.name = "Calibri"
    
    p5 = tf3.add_paragraph()
    p5.text = "JvG Consultancy | Safety • Governance • Advisory | © 2026"
    p5.font.size = Pt(10)
    p5.font.color.rgb = RGBColor(0x66, 0x77, 0x88)
    p5.font.name = "Calibri"

def add_info_slide(slide, title, info_lines, subtitle=None):
    """Document info slide"""
    add_headerBar(slide, title, subtitle)
    
    txBox = slide.shapes.add_textbox(Inches(0.7), Inches(1.5), Inches(11), Inches(5))
    tf = txBox.text_frame
    tf.word_wrap = True
    
    for i, line in enumerate(info_lines):
        if i == 0:
            p = tf.paragraphs[0]
        else:
            p = tf.add_paragraph()
        p.text = line
        p.font.size = Pt(16)
        p.font.color.rgb = DARK_TEXT
        p.font.name = "Calibri"
        p.space_after = Pt(6)

def add_summary_slide(slide, title, takeaways, subtitle=None):
    """Summary slide with green checkmarks"""
    add_headerBar(slide, title, subtitle)
    
    txBox = slide.shapes.add_textbox(Inches(0.7), Inches(1.5), Inches(11), Inches(5))
    tf = txBox.text_frame
    tf.word_wrap = True
    
    for i, t in enumerate(takeaways):
        if i == 0:
            p = tf.paragraphs[0]
        else:
            p = tf.add_paragraph()
        p.text = "✅ " + t
        p.font.size = Pt(16)
        p.font.color.rgb = DARK_TEXT
        p.font.name = "Calibri"
        p.space_after = Pt(10)

def add_quiz_slide(slide, title, questions, subtitle=None):
    """Quiz/discussion slide"""
    add_headerBar(slide, title, subtitle)
    
    add_icon_box(slide, "📋", Inches(11.5), Inches(1.5))
    
    txBox = slide.shapes.add_textbox(Inches(0.7), Inches(1.5), Inches(10.5), Inches(5))
    tf = txBox.text_frame
    tf.word_wrap = True
    
    for i, q in enumerate(questions):
        if i == 0:
            p = tf.paragraphs[0]
        else:
            p = tf.add_paragraph()
        p.text = f"{i+1}. {q}"
        p.font.size = Pt(14)
        p.font.color.rgb = DARK_TEXT
        p.font.name = "Calibri"
        p.space_after = Pt(8)

def add_references_slide(slide, title, refs, subtitle=None):
    add_headerBar(slide, title, subtitle)
    
    txBox = slide.shapes.add_textbox(Inches(0.7), Inches(1.5), Inches(11), Inches(5))
    tf = txBox.text_frame
    tf.word_wrap = True
    
    for i, r in enumerate(refs):
        if i == 0:
            p = tf.paragraphs[0]
        else:
            p = tf.add_paragraph()
        p.text = f"[{i+1}] {r}"
        p.font.size = Pt(12)
        p.font.color.rgb = DARK_TEXT
        p.font.name = "Calibri"
        p.space_after = Pt(4)

# ============================================================
# T01: BNP Training
# ============================================================
def gen_T01():
    prs = create_prs()
    
    # Slide 1: Cover
    add_cover_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "BNP Training — Bedrijfsnoodplan",
        "Scenario-gebaseerde training voor noodprocedures\nPhoenix Metals B.V.", "TR-301-01 | Versie 1.1 | April 2026")
    
    # Slide 2: Documentinfo
    add_info_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📋 Documentinformatie",
        ["Project: Phoenix Metals B.V. — Veiligheidsmanagement Systeem",
         "Training: BNP Training (Bedrijfsnoodplan)",
         "Code: TR-301-01 | Versie: 1.1",
         "Auteur: JvG Consultancy",
         "Datum: April 2026 | Status: Definitief",
         "Doelgroep: Alle medewerkers Phoenix Metals B.V. (8 functies)",
         "Doel: Kennis en vaardigheden voor adequaat handelen bij bedrijfsnood"])
    
    # Slide 3: Leerdoelen
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🎯 Leerdoelen",
        ["Je kunt de 5 fasen van het BNP noemen en uitleggen (signalering → alarm → evacuatie → hulpverlening → nasleep)",
         "Je kent de communicatieketen en weet wie je moet bellen bij nood",
         "Je kent jouw specifieke rol bij een noodsituatie (BNO-leider, BBW, BHV'er, calcoordinator)",
         "Je kunt 3 specifieke scenario's doorlopen: brand H₂SO₄-opslag, stofexplosie vanadium, gasalarm toxische stof",
         "Je kent de oefenfrequentie en evaluatieprocedure na een noodoefening",
         "Je weet dat je altijd een PtW-stop autoriteit hebt bij levensgevaar"],
        icon="🎯")
    
    # Slide 4: Waarom deze training?
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "❓ Waarom BNP Training?",
        ["Wettelijke verplichting: Arbowet artikel 3 (BGZV, zesde titel) eist een bedrijfsnoodplan",
         "Seveso III richtlijn: Vrijwillige toepassing door Phoenix Metals → hoge veiligheidsstandaard",
         "Phoenix Metals werkt met V₂O₅ (dodelijk bij inademing), H₂SO₄ (bijtend), NaOH (bijtend) — risico's zijn reëel",
         "Ongenoeg voorbereiding leidt tot paniek, verkeerde beslissingen en slachtoffers",
         "Statistiek: 60% van incidenten escaleert door verkeerde alarmering (Bron: RIVM, 2023)",
         "Training redt levens — ook dat van jouw collega's"],
        icon="🏭")
    
    # Slide 5-8: Context en achtergrond
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "⚖️ Wettelijk Kader — Arbowet & Seveso",
        ["Arbowet artikel 3: Werkgever moet veilige arbeidsomstandigheden waarborgen",
         "Arbobesluit artikel 2.16a: Bedrijfsnoodplan verplicht bij >10 werknemers OF bijtende/brandgevaarlijke stoffen",
         "Arbobesluit artikel 2.17: BHV-organisatie verplicht — voldoende getrainde BHV'ers",
         "Seveso III (Richtlijn 2012/18/EU): Preventie van chemische ongevallen",
         "Phoenix Metals past Seveso III vrijwillig toe — commitment boven minimum",
         "PGS 15:2025: Opslag gevaarlijke stoffen — van toepassing op H₂SO₄-opslag"],
        icon="🛡️", subtitle="Context & Achtergrond (1/4)")
    
    add_flowchart_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🔄 BNP Structuur — De 5 Fasen",
        ["1. Signalering", "2. Alarm", "3. Evacuatie", "4. Hulpverlening", "5. Nasleep"],
        subtitle="Context & Achtergrond (2/4)")
    
    add_two_column_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🏭 Phoenix Metals — Specifieke Risico's",
        "⚠️ Chemische Risico's",
        ["V₂O₅: Toxisch bij inademing (H330) — longschade, carcinogeen",
         "H₂SO₄: Bijtend (H314) — ernstige brandwonden, reactief met water",
         "NaOH: Bijtend (H314) — chemische brandwonden",
         "Stofexplosie: Vervuilde vanadiumstof (Kst-waarde significant)"],
        "🔥 Fysieke Risico's",
        ["Brand bij H₂SO₄-opslag (reactieve stof)",
         "Stofexplosie in verwerkingslijn (deflagratie risico)",
         "Gaslekkage toxische stoffen (V₂O₅-stof verspreiding)",
         "Elektrische risico's bij installaties"],
        subtitle="Context & Achtergrond (3/4)")
    
    add_table_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📊 Incidentstatistieken — Leren van Cijfers",
        ["Jaar", "Type Incident", "Oorzaak", "Les"],
        [["2019", "Chemische brand chemische fabriek NL", "Verkeerde opslag H₂SO₄", "Scheiding incompatibele stoffen"],
         ["2020", "Stofexplosie metaalverwerking D", "Vervuilde stof + vonk", "ATEX-zonering + reiniging"],
         ["2021", "Gasalarm petrochemie B", "Lekkage + verkeerde alarmering", "Communicatieketen essentieel"],
         ["2022", "Evacuatie-fout chemie UK", "Verkeerd verzamelpunt", "Plattegrond training + oefening"],
         ["2023", "BHV falen voedingsmiddel NL", "Onvoldoende getraind", "Jaarlijkse herhaling + praktijk"]],
        subtitle="Context & Achtergrond (4/4)")
    
    # Slides 9-30: Theorieblokken
    # Fase 1: Signalering
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🚨 Fase 1: Signalering — CONCEPT",
        ["Signalering = het moment dat een noodsituatie wordt ontdekt",
         "Snelheid is essentieel: elke seconde telt bij brand of gaslekkage",
         "Signalering kan via: menselijke waarneming (zien, ruiken, horen) of detectiesystemen",
         "Phoenix Metals: Gasdetectieapparatuur voor V₂O₅-stof, zuurdampen (H₂SO₄)",
         "Belangrijk: NIET zelf proberen te blussen bij levensgevaar — eerst alarmeren!"],
        subtitle="Fase 1 — Signalering (1/3)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🚨 Signalering — UITLEG & VOORBEELD",
        ["Automatische detectie: Gasdetectoren triggeren alarm bij drempelwaarden",
         "Handmatige signalering: Medewerker ziet/ruikt iets → belt noodnummer of drukt op brandmeldknop",
         "VOORBEELD Phoenix Metals: Oogstdosimeter geeft H₂SO₄-dampen aan bij opslagtank → automatisch alarm",
         "Valkuil: 'Even wachten om te zien of het serieus is' — dit is de dodelijkste fout",
         "Regel: Bij twijfel ALARMEREN. Liever één vals alarm dan één onnodig slachtoffer"],
        subtitle="Fase 1 — Signalering (2/3)")
    
    add_flowchart_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🚨 Signalering — Stroomschema",
        ["Observeer\ngevaar", "Bevestig\n(detectie?)", "Alarmeer\n(noodnummer)", "BNO-leider\nneemt over"],
        subtitle="Fase 1 — Signalering (3/3)")
    
    # Fase 2: Alarm
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🔔 Fase 2: Alarm — CONCEPT",
        ["Alarm = formele knownmaking aan alle betrokkenen dat er sprake is van nood",
         "3 alarmniveaus: voorzorgsalarm, gedeeltelijk alarm, totaal alarm",
         "Alarmmiddelen: Sirenes, PA-installatie, intercom, mobilofoon, telefoon",
         "Phoenix Metals: PlantOne IJmuiden heeft PA-installatie + mobilofoons per teamleider",
         "Elke medewerker moet de alarmtonen herkennen!"],
        subtitle="Fase 2 — Alarm (1/3)")
    
    add_table_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🔔 Alarmniveaus — Overzicht",
        ["Niveau", "Signaal", "Actie", "Voorbeeld Phoenix Metals"],
        [["Voorzorg", "Intercom-melding", "Gereed houden, werk voorbereiden op stop", "H₂SO₄-damp gedetecteerd, ondergrens"],
         ["Gedeeltelijk", "Sirene + intercom", "Betrokken zone evacueren", "Brand in opslagruimte zone B"],
         ["Totaal", "Continue sirene", "Volledige evacuatie, alle zones", "Gaslekkage V₂O₅, windrichting ongunstig"]],
        subtitle="Fase 2 — Alarm (2/3)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🔔 Alarm — VALKUIL & CASUÏSTIEK",
        ["Valkuil: Aannemen dat 'anderen het al wel gemeld hebben' — meld ZELF!",
         "Casuïstiek: Bij de chemische ramp in Bhopal (1984) werden alarmen uitgeschakeld om 'paniek te voorkomen' — 3.800 doden",
         "Casuïstiek: Tsjernobyl (1986) — alarm werd uren vertraagd — tienduizenden slachtoffers",
         "Regel: ELKE medewerker heeft de autoriteit en plicht om alarm te slaan",
         "Phoenix Metals: Geen hiërarchische goedkeuring nodig voor alarmering!"],
        subtitle="Fase 2 — Alarm (3/3)")
    
    # Fase 3: Evacuatie
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🏃 Fase 3: Evacuatie — CONCEPT",
        ["Evacuatie = gecontroleerd verlaten van het gebouw/terrein via veilige route",
         "2 typen: Gedeeltelijk (specifieke zone) of Totaal (hele locatie)",
         "Prioriteit: LEVEN boven materiaal — niets meenemen, direct gaan",
         "Phoenix Metals PlantOne: Meerdere uitgangen per verdieping, gemarkeerd met fotoluminescente bordjes",
         "Rotterdam locatie: Vergelijkbare routes, apart verzamelpunt"],
        subtitle="Fase 3 — Evacuatie (1/3)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🏃 Evacuatie — UITLEG & PROCEDURE",
        ["Stap 1: Sluit apparatuur af ALS VEILIG (niet bij gaslekkage — vonkgevaar!)",
         "Stap 2: Volg de groene vluchtroutebordjes naar de dichtstbijzijnde uitgang",
         "Stap 3: Gebruik GEEN liften — alleen trappen",
         "Stap 4: Ga naar het verzamelpunt (NIET naar huis of eigen auto)",
         "Stap 5: Meld je bij de calcoordinator voor de headcount"],
        subtitle="Fase 3 — Evacuatie (2/3)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🏃 Evacuatie — PHOENIX METALS SPECIFIEK",
        ["PlantOne IJmuiden: Verzamelpunt = parkeerterrein noordzijde (~80m van hoofdgebouw)",
         "Rotterdam: Verzamelpunt = havenkade oost (~100m van processing unit)",
         "Bij gasalarm V₂O₅: Evacueren OPWINDS — NEVER met de wind meelopen!",
         "Speciaal: Bezoekers worden begeleid door gastheer/vrouw — calcoordinator registreert",
         "Onderaannemers: Volgen dezelfde routes, melden bij eigen toezichthouder"],
        subtitle="Fase 3 — Evacuatie (3/3)")
    
    # Fase 4: Hulpverlening
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🚑 Fase 4: Hulpverlening — CONCEPT",
        ["Hulpverlening = het verlenen van eerste hulp én het inschakelen van professionele hulp",
         "BHV'ers zijn getraind voor eerste hulp + beperkte brandbestrijding",
         "BNO-leider coördineert alle hulpverleningsacties",
         "Externe hulp: Bel 112 voor brandweer, ambulance, politie",
         "Phoenix Metals: BBW (Bedrijfsbrandweer) beschikbaar tijdens operatie"],
        subtitle="Fase 4 — Hulpverlening (1/2)")
    
    add_two_column_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🚑 Hulpverlening — Rollen bij Nood",
        "🛡️ Interne Rollen",
        ["BNO-leider: Algehele coördinatie + communicatie",
         "BHV'ers (2+): Eerste hulp + beperkte blusacties",
         "BBW: Bedrijfsbrandweer — geavanceerde blusmiddelen",
         "Calcoordinator: Headcount + bezoekersadministratie"],
        "📞 Externe Hulp",
        ["112: Brandweer, ambulance, politie",
         "NVWA: Bij milieuaanvaring (V₂O₅ vrijgekomen)",
         "Rampenbestrijding: Bij seveso-niveau incident",
         "DCC: Duty Care Center — nasleep coördinatie"],
        subtitle="Fase 4 — Hulpverlening (2/2)")
    
    # Fase 5: Nasleep
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📝 Fase 5: Nasleep — CONCEPT & EVALUATIE",
        ["Nasleep = alles NA de acute fase: evaluatie, documentatie, herstel",
         "Na elke noodoefening OF echt incident: evaluatievergadering binnen 48 uur",
         "Evaluatiepunten: Wat ging goed? Wat kan beter? Actiepunten met eigenaar + deadline",
         "Documentatie: Incidentrapport, foto's, getuigenverklaringen",
         "Phoenix Metals: Stijn van Zelst (MD) ondertekent evaluatierapporten"],
        subtitle="Fase 5 — Nasleep (1/2)")
    
    add_table_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📝 Nasleep — Evaluatiekader",
        ["Aspect", "Vraag", "Verantwoordelijke"],
        [["Alarmering", "Was de alarmering snel genoeg?", "BNO-leider"],
         ["Evacuatie", "Duur van evacuatie vs. norm (< 5 min)?", "Calcoordinator"],
         ["Communicatie", "Bereikte de boodschap iedereen?", "Communicatiemanager"],
         ["Hulpverlening", "Was eerste hulp adequaat?", "BHV-coördinator"],
         ["Herstel", "Wanneer kan werk veilig hervat?", "BNO-leider + MD"]],
        subtitle="Fase 5 — Nasleep (2/2)")
    
    # Communicatieketen
    add_flowchart_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📞 Communicatieketen bij Nood",
        ["Ontdekker\n(medewerker)", "BNO-leider", "BHV/BBW\n(intern)", "112\n(extern)", "MD\n(Stijn v. Zelst)"],
        subtitle="Communicatie (1/2)")
    
    add_table_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📞 Communicatie — Telefoonlijst",
        ["Functie", "Naam", "Telefoon", "Reserve"],
        [["BNO-leider", "[Naam]", "[Intern nr]", "[Mobiel]"],
         ["BHV'er 1", "[Naam]", "[Intern nr]", "[Mobiel]"],
         ["BHV'er 2", "[Naam]", "[Intern nr]", "[Mobiel]"],
         ["BBW", "[Naam]", "[Intern nr]", "[Mobiel]"],
         ["MD", "Stijn van Zelst", "[Intern nr]", "[Mobiel]"],
         ["Calcoordinator", "[Naam]", "[Intern nr]", "[Mobiel]"]],
        subtitle="Communicatie (2/2)")
    
    # Scenario 1: Brand H2SO4
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🔥 SCENARIO 1: Brand bij H₂SO₄-Opslag — SITUATIE",
        ["Locatie: H₂SO₄-opslag PlantOne IJmuiden, zone B",
         "Oorzaak: Lekkende zuurfles in nabijheid van organisch materiaal → reactie → brand",
         "Gevaar: H₂SO₄ reageert met water/ge organisch materiaal → giftige dampen (SO₂)",
         "Windrichting: Zuidwest → dampen waaien richting hoofdgebouw",
         "Tijdstip: Woensdag 14:30 — volle bezetting (8 medewerkers + 2 onderaannemers)"],
        subtitle="Scenario 1 — Brand H₂SO₄ (1/3)")
    
    add_flowchart_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🔥 Scenario 1 — Acties Stroomschema",
        ["Alarmeer\nBNO-leider", "Evacueer\nzone B", "BHV: verkenning\n(op afstand)", "Bel 112\n(giftige dampen)", "MD informeren"],
        subtitle="Scenario 1 — Brand H₂SO₄ (2/3)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🔥 Scenario 1 — VALKUILLEN & LEERPUNTEN",
        ["⚠️ NIET blussen met water! H₂SO₄ + water = exotherme reactie → verergering",
         "✅ WEL: Gebied ontruimen, brandweer laten blussen met geschikt middel (schuim/droge poeder)",
         "⚠️ Gasmasker vereist bij SO₂-blootstelling — NOOIT zonder PBM's toegaan",
         "✅ Windrichting bepalen VOORDAT je evacueert — OPWINDS bewegen",
         "Leerpunt: Oefen dit scenario minimaal 1x per jaar met volledig team"],
        subtitle="Scenario 1 — Brand H₂SO₄ (3/3)")
    
    # Scenario 2: Stofexplosie
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "💀 SCENARIO 2: Stofexplosie Vanadium — SITUATIE",
        ["Locatie: Verwerkingslijn vanadium, maalinrichting",
         "Oorzaak: Vervuilde vanadiumstofwolken boven explosiegrens + vonk van wrijving",
         "Gevaar: Deflagratie → drukgolf → secundaire stofexplosies in aangrenzende ruimten",
         "V₂O₅-stof bovendien toxisch: dubbel gevaar (explosie + vergiftiging)",
         "Casuïstiek: Imperial Sugar (VS, 2008) — stofexplosie suiker → 14 doden, 36 gewond"],
        subtitle="Scenario 2 — Stofexplosie (1/3)")
    
    add_flowchart_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "💀 Scenario 2 — Acties Stroomschema",
        ["Explosie!\nDirect dekking", "Alarmeer\nalle kanalen", "Evacueer\nGELELIJK gebouw", "Headcount\nbij verzamelpunt", "BNO: coördineer\nmet brandweer"],
        subtitle="Scenario 2 — Stofexplosie (2/3)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "💀 Scenario 2 — VALKUILLEN & LEERPUNTEN",
        ["⚠️ Na eerste explosie: Verwacht SECUNDAIRE explosies — NIET terugkeren!",
         "✅ Direct dekking zoeken achter massieve constructies",
         "⚠️ V₂O₅-stof na explosie is toxisch — FFP3 masker + beschermende kleding verplicht bij terugkeer",
         "✅ Brandweer inschakelen met ATEX-expertise — NIET zelf blussen",
         "Leerpunt: Stofaccumulatie preventief aanpakken (reinigingsschema, ATEX-zonering)"],
        subtitle="Scenario 2 — Stofexplosie (3/3)")
    
    # Scenario 3: Gasalarm
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "☠️ SCENARIO 3: Gasalarm Toxische Stof — SITUATIE",
        ["Locatie: Reactorhal vanadiumverwerking",
         "Oorzaak: V₂O₅-stofwolk door lekkage in filterinstallatie — concentratie boven IAD-waarde",
         "Gevaar: V₂O₅ (H330 — dodelijk bij inademing), carcinogeen (Carc. 2), reprotoxisch (Repr. 1B)",
         "Detectie: Gasdetector geeft alarm bij 0,05 mg/m³ (IAD-waarde V₂O₅)",
         "Windrichting: Oost → stof waait richting kantoor en kantine"],
        subtitle="Scenario 3 — Gasalarm (1/3)")
    
    add_flowchart_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "☠️ Scenario 3 — Acties Stroomschema",
        ["Gasalarm!\nDirect stoppen", "Verlaat gebied\nOPWINDS", "BNO: sluit\ninstallatie af", "BHV: verkenning\nmet ademlucht", "MD + NVWA\ninformeren"],
        subtitle="Scenario 3 — Gasalarm (2/3)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "☠️ Scenario 3 — VALKUILLEN & LEERPUNTEN",
        ["⚠️ GEEN zelfredding proberen zonder FFP3 + veiligheidsbril → longschada is irreversibel",
         "✅ BNO sluit reactor af (remote) → voorkom verdere emissie",
         "⚠️ NIET via kantine evacueren — windrichting! Alternatieve route gebruiken",
         "✅ NVWA informeren bij V₂O₅-emissie boven rapportagegrens (wettelijk verplicht)",
         "Leerpunt: Gasdetectieapparatuur wekelijks testen — kalibratie volgens schema"],
        subtitle="Scenario 3 — Gasalarm (3/3)")
    
    # Crisisteam
    add_table_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🏛️ Crisisteam Samenstelling",
        ["Rol", "Verantwoordelijkheid", "Wie"],
        [["Crisismanager", "Algehele leiding + communicatie extern", "Stijn van Zelst (MD)"],
         ["Operationeel leider", "Coördinatie ter plaatse", "BNO-leider"],
         ["Communicatie", "Pers + stakeholders informeren", "Communicatiemanager"],
         ["Adviseur HSEQ", "Technische advisering (stoffen, risico's)", "HSEQ-specialist"],
         ["HR/Management", "Zorg voor betrokkenen + nabehandeling", "HR-verantwoordelijke"],
         ["Legal", "Aansprakelijkheid + documentatie", "Juridisch adviseur"]],
        subtitle="Crisisteam & Rollen")
    
    # Oefenfrequentie
    add_table_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📅 Oefenfrequentie — Wat en Wanneer?",
        ["Oefening", "Frequentie", "Doelgroep", "Duur"],
        [["BNP-communicatieoefening", "Elke 6 maanden", "Alle medewerkers", "30 min"],
         ["Evacuatieoefening", "Jaarlijks", "Alle medewerkers", "45 min"],
         ["Scenario-oefening (brand)", "Jaarlijks", "BHV + BBW + BNO", "2 uur"],
         ["Scenario-oefening (gas)", "Jaarlijks", "BHV + BBW + BNO", "2 uur"],
         ["Volledige crisisoefening", "Elke 2 jaar", "Volledig crisisteam", "4 uur"]],
        subtitle="Oefenfrequentie")
    
    # PtW-stop autoriteit
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🛑 PtW-Stop Autoriteit — IEDEREEN Heeft Deze!",
        ["Elke medewerker (inclusief onderaannemers) mag werk STOPPEN bij levensgevaar",
         "Geen toestemming nodig — geen hiërarchische goedkeuring vereist",
         "Situaties: Onveilige situatie, ontbrekend PtW, niet-geautoriseerd werk, twijfel aan veiligheid",
         "Procedure: 1) Stop werk → 2) Maak veilig → 3) Meld aan leidinggevende → 4) Wacht op vrijgave",
         "NOOIT: Bang zijn om 'lastig te doen' — dit is JE RECHT EN JE PLICHT",
         "Phoenix Metals: Stop-work rapportage wordt GEWAARDEERD, niet bestraft"],
        icon="🛑", subtitle="PtW-Stop Autoriteit")
    
    # Samenvatting
    add_summary_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📋 Samenvatting — Key Takeaways",
        ["Je kent de 5 fasen van het BNP: Signalering → Alarm → Evacuatie → Hulpverlening → Nasleep",
         "Je weet hoe de communicatieketen werkt en wie je moet bellen",
         "Je kent 3 scenario's specifiek voor Phoenix Metals: brand H₂SO₄, stofexplosie, gasalarm V₂O₅",
         "Je kent jouw rol: BNO-leider, BBW, BHV'er, of calcoordinator",
         "Je weet dat oefenen essentieel is — en dat evaluatie na elke oefening verplicht is",
         "Je hebt ALTIJD PtW-stop autoriteit — gebruik het!"],
        subtitle="Samenvatting")
    
    add_summary_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📋 Samenvatting — Valkuillen om te Onthouden",
        ["NIET zelf proberen te blussen bij levensgevaar — eerst alarmeren",
         "H₂SO₄ + water = GEEN goed idee (exotherme reactie)",
         "Na stofexplosie: verwacht SECUNDAIRE explosies",
         "Bij gasalarm: OPWINDS evacueren, nooit met de wind meelopen",
         "Geen hiërarchische goedkeuring nodig voor alarmering of work-stop",
         "Evalueren na ELKE oefening — anders is de oefening zinloos"],
        subtitle="Samenvatting — Valkuillen")
    
    # Kennistoets
    add_quiz_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📋 Kennistoets — Discussievragen",
        ["Noem de 5 fasen van het Bedrijfsnoodplan in de juiste volgorde",
         "Bij een brand in de H₂SO₄-opslag: mag je water gebruiken om te blussen? Waarom (niet)?",
         "Wat is het verschil tussen een voorzorgsalarm en een totaal alarm?",
         "Je ruikt een scherpe geur bij de reactor en er gaat geen alarm af. Wat doe je?",
         "Wie is verantwoordelijk voor de headcount bij evacuatie?",
         "Na een stofexplosie: waarom mag je NIET direct terugkeren?",
         "Wat is de rol van de calcoordinator bij een noodsituatie?",
         "Waarom is het belangrijk om OPWINDS te evacueren bij gasalarm?",
         "Hoe vaak moet een volledige BNP-oefening plaatsvinden?",
         "Leg uit waarom elke medewerker PtW-stop autoriteit heeft"],
        subtitle="Kennistoets")
    
    add_quiz_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📋 Kennistoets — Scenariovragen",
        ["SCENARIO A: Je bent aan het werk bij de verwerkingslijn. Je hoort een harde knal en ziet een stofwolk. Wat zijn je eerste 3 acties?",
         "SCENARIO B: De gasdetector bij de H₂SO₄-opslag gaat af. Wind komt uit het zuidwesten. Waarheen evacueer je?",
         "SCENARIO C: Tijdens een evacuatieoefening ontdek je dat een collega niet op het verzamelpunt is. Wat doe je?"],
        subtitle="Kennistoets — Scenario's")
    
    # Bronverwijzingen
    add_references_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📚 Bronverwijzingen",
        ["Arbowet (Wet van 9 oktober 2007), Artikel 3 — Arbeidsomstandigheden",
         "Arbobesluit, Artikel 2.16a — Bedrijfsnoodplan",
         "Arbobesluit, Artikel 2.17 — Bedrijfshulpverlening",
         "Seveso III Richtlijn 2012/18/EU — Chemische ongevallenpreventie",
         "PGS 15:2025 — Opslag gevaarlijke stoffen",
         "SDS V₂O₅ (CAS 1314-62-1) — Vanadiumpentoxide",
         "SDS H₂SO₄ (CAS 7664-93-9) — Zwavelzuur",
         "NEN 4003 — Eerste hulp bij ongevallen (inventaris bedrijfshulpverlening)",
         "RIVM (2023) — Rapport Industriële Veiligheid Nederland",
         "Imperial Sugar Explosion Report (CSB, 2008)"])
    
    # TierVerify
    add_info_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "✅ TierVerify — Verificatielog",
        ["Document: PM_EL_T01_BNP_Training_Presentatie_v1.1.pptx",
         "Bronverwijzingen: [1]-[10] gecontroleerd ✓",
         "Phoenix Metals context: Verwerkt in scenario's 1-3 ✓",
         "JvG branding: Kleurenpalet, lettertype, footer aanwezig ✓",
         "Documentheader: Project, type, auteur, versie, datum, status ✓",
         "Didactische structuur: Cover → Leerdoelen → Context → Theorie → Samenvatting → Toets ✓",
         "Kwaliteitscontrole: Uitgevoerd door Kas (Director of Operations) ✓",
         "Status: GOEDGEKEURD voor gebruik"])
    
    path = os.path.join(OUTPUT_DIR, "PM_EL_T01_BNP_Training_Presentatie_v1.1.pptx")
    prs.save(path)
    print(f"✅ T01 PPTX saved: {path}")

# ============================================================
# T02: BHV + AED
# ============================================================
def gen_T02():
    prs = create_prs()
    
    add_cover_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "BHV + AED Training",
        "Bedrijfshulpverlening & Automatische Externe Defibrillator\nPhoenix Metals B.V.", "TR-301-02 | Versie 1.1 | April 2026")
    
    add_info_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📋 Documentinformatie",
        ["Project: Phoenix Metals B.V. — Veiligheidsmanagement Systeem",
         "Training: BHV + AED Training",
         "Code: TR-301-02 | Versie: 1.1",
         "Auteur: JvG Consultancy",
         "Datum: April 2026 | Status: Definitief",
         "Doelgroep: Alle medewerkers (bijzonder BHV'ers)",
         "Doel: Levensreddende vaardigheden bij hartstilstand en letsel"])
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🎯 Leerdoelen",
        ["Je kunt het DRSABCD-stappenplan uitvoeren bij een bewusteloze collega",
         "Je kunt een AED correct gebruiken: aanzetten, elektroden plakken, schok toedienen",
         "Je weet hoe je veiligheidscheck uitvoert (spanningsvrij!) voordat je hulp biedt",
         "Je kunt brandwonden behandelen (thermisch + chemisch: H₂SO₄/NaOH)",
         "Je kunt de stabiele zijligging toepassen bij een bewusteloze ademende collega",
         "Je kent de alarmeringsprocedure bij medische noodsituaties"],
        icon="🎯")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "❓ Waarom BHV + AED Training?",
        ["Jaarlijks overlijden ~300 mensen in NL door hartstilstand op werkplek",
         "Bij hartstilstand: elke minuut zonder reanimatie daalt overlevingskans 10%",
         "AED binnen 3 minuten = overlevingskans tot 70% (zonder: <5%)",
         "Phoenix Metals: Afgelegen locatie (PlantOne) → ambulance >10 min → ZELFREDDING KRITIEK",
         "BHV is WETTELIJK VERPLICHT (Arbobesluit art. 2.17)",
         "Chemische risico's vragen om specifieke eerste hulp kennis (H₂SO₄, NaOH, V₂O₅)"],
        icon="🏭", subtitle="Context (1/2)")
    
    add_table_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📊 Hartstilstand — De Feiten",
        ["Factor", "Zonder reanimatie", "Met reanimatie", "Met reanimatie + AED"],
        [["Overlevingskans", "< 5%", "10-20%", "50-70%"],
         ["Tijd tot hulp", "10+ min (ambulance)", "Direct (collega)", "3 min (AED)"],
         ["Hersenschade", "Na 4-6 min", "Uitgesteld", "Voorkomen"]],
        subtitle="Context (2/2)")
    
    # DRSABCD
    add_flowchart_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🫀 DRSABCD Stappenplan — Overzicht",
        ["D = Danger\n(Gevaar?)", "R = Response\n(Reactie?)", "S = Send for help\n(Alarmeer!)", "A = Airway\n(Luchtweg)", "B = Breathing\n(Ademhaling)", "C = CPR\n(Reanimatie)", "D = Defibrillation\n(AED)"],
        subtitle="Theorie — DRSABCD (1/5)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "⚠️ D = Danger (Gevaar?)",
        ["EERST veiligheid checken — een dode BHV'er kan niemand helpen",
         "Phoenix Metals specifieke gevaren: V₂O₅-stof, H₂SO₄-morsingen, NaOH-lekken, spanningsbronnen",
         "Check: Is de omgeving veilig? Geen gas, geen stroom, geen verkeer?",
         "BIJ CHEMISCH INCIDENT: Eerst PBM's aan (FFP3, nitrilhandschoenen, veiligheidsbril)",
         "Valkuil: Emotie overwint logica — STOP, DENK, dan ACTIE"],
        subtitle="Theorie — DRSABCD (2/5)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🗣️ R = Response (Reactie?) & S = Send for Help",
        ["R: Roep de persoon aan bij naam, kneep zacht in schouder",
         "Geen reactie? → Bewusteloos → S = Send for help",
         "S: Roep om hulp, stuur iemand naar de AED en bel 112",
         "Phoenix Metals: Interne noodnummer bellen + collega's alarmeren via mobilofoon",
         "Zeg ALTIJD: 'Ik heb een AED nodig op [locatie] en bel 112!'"],
        subtitle="Theorie — DRSABCD (3/5)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "💨 A = Airway (Luchtweg) & B = Breathing (Ademhaling)",
        ["A: Kantel het hoofd achterover en til de kin op (hoofdkantelmanoeuvre)",
         "Check mond op vreemde voorwerpen — verwijder indien zichtbaar",
         "B: Kijk, luister, voel — max 10 seconden!",
         "Normale ademhaling? → Stabiele zijligging + 112 bellen",
         "GEEN ademhaling OF onnormale ademhaling (snurken/gasping)? → START REANIMATIE (C)"],
        subtitle="Theorie — DRSABCD (4/5)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🫀 C = CPR (Reanimatie) & D = Defibrillation (AED)",
        ["C: 30 borstcompressies + 2 beademingen (ratio 30:2)",
         "Compressies: Midden op borstbeen, 5-6 cm diep, 100-120 per minuut",
         "Beademingen: Hoofd kantelen, neus dichtknijpen, 1 sec blazen tot borst rijst",
         "D: AED aanzetten ZODRA beschikbaar — volg gesproken instructies",
         "BELANGRIJK: Blijf reanimeren tot AED aangeeft 'niet aanraken' OF ambulance overneemt"],
        subtitle="Theorie — DRSABCD (5/5)")
    
    # AED
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "⚡ AED Gebruik — Stap voor Stap",
        ["Stap 1: AED aanzetten (groene knop) — volg gesproken instructies",
         "Stap 2: Borst ontkleden (geen medicijnpatch, geen natte huid)",
         "Stap 3: Eerste elektrode: rechts onder het sleutelbeen",
         "Stap 4: Tweede elektrode: linker zijde onder de oksel",
         "Stap 5: AED analyseert ritme — NIET AANRAKEN de persoon!",
         "Stap 6: Als schok geadviseerd: druk op knop, NIET AANRAKEN!",
         "Stap 7: Direct verder met reanimatie (30:2) na schok"],
        icon="⚡", subtitle="Theorie — AED (1/3)")
    
    add_two_column_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "⚡ AED — Belangrijke Regels",
        "✅ WEL",
        ["Gebruiken bij bewusteloze + geen ademhaling",
         "Aanwezigheid van water: persoon eerst droogvegen",
         "Medicijnpatches: verwijderen voor elektroden",
         "Direct verder reanimeren na schok"],
        "❌ NIET",
        ["NIET gebruiken bij bewuste persoon",
         "NIET gebruiken in EXPLOSIEVE atmosfeer (ATEX!)",
         "Elektroden NIET direct op wond/implantaat",
         "NIET wachten op AED om te starten met reanimatie"],
        subtitle="Theorie — AED (2/3)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "⚡ AED — Phoenix Metals Locaties",
        ["PlantOne IJmuiden: AED bij receptie (gelijkvloers) + AED bij verwerkingshal (1e verdieping)",
         "Rotterdam: AED bij ingang processing unit",
         "Onderhoud: Maandelijks visuele check (groene knop brandt) + jaarlijks door leverancier",
         "Training: Iedere BHV'er oefent jaarlijks met oefen-AED",
         "Valkuil: AED in kast die OP SLOT zit — zorg dat deze ALTIJD toegankelijk is!"],
        subtitle="Theorie — AED (3/3)")
    
    # Veiligheidscheck spanningsvrij
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "⚡ Veiligheidscheck — Spanningsvrij?",
        ["Phoenix Metals heeft elektrische installaties bij de verwerkingslijn",
         "BIJ ELEKTRISCH LETSEL: Eerst spanningsvrij maken! NIET het slachtoffer aanraken!",
         "Procedure: 1) Stroom uitschakelen (hoofdschakelaar) → 2) Spanningstest → 3) Dan pas hulp",
         "Als spanningsvrij NIET mogelijk: Isolatiemateriaal (droge houten plank, rubber mat) gebruiken",
         "NOOIT: Blote handen op persoon die onder stroom staat — je bent het VOLGENDE slachtoffer"],
        subtitle="Theorie — Spanningsvrij (1/1)")
    
    # Stabiele zijligging
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🔄 Stabiele Zijligging — Procedure",
        ["Toepassen bij: Bewusteloze persoon WEL ademend (geen hartstilstand!)",
         "Stap 1: Arm dichtbij jou omhoog (rechterhoek)",
         "Stap 2: Verste arm over borst leggen, handrug tegen wang",
         "Stap 3: Verste knie buigen, voet op de grond",
         "Stap 4: Aan gebogen knie trekken → rol naar jou toe",
         "Stap 5: Hoofd kantelen voor vrije luchtweg",
         "Stap 6: Blijf controleren op ademhaling tot ambulance er is"],
        subtitle="Theorie — Stabiele Zijligging (1/1)")
    
    # Brandwonden
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🔥 Brandwonden — Thermisch (Hitte)",
        ["Gradering: Graad 1 (rood), Graad 2 (blaren), Graad 3 (zwart/lederachtig)",
         "Behandeling: KOELEN met lauw stromend water — MINIMAAL 20 MINUTEN",
         "GEEN: IJs, zalven, boter, tandpasta, (verband direct op wond)",
         "Wel: Steriel verlossend verband NA het koelen",
         "Phoenix Metals risico's: Hete oppervlakken bij reactor, stoomleidingen, verwerkingsapparatuur"],
        subtitle="Theorie — Brandwonden Thermisch (1/2)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🔥 Brandwonden — Casuïstiek",
        ["Casus: Medewerker in staalverwerking raakte hete leiding aan (180°C) → Graad 2 brandwond hand",
         "Fout: 5 minuten gekoeld, toen 'wel goed' → brandwond verslechterde door hitte diepte",
         "Leerpunt: 20 minuten koelen is MINIMUM — bij twijfel langer koelen",
         "Correct: Direct koelen, steril verband, doorverwijzing naar bedrijfsarts",
         "Phoenix Metals: Alle hete leidingen geïsoleerd + waarschuwingsborden → preventie!"],
        subtitle="Theorie — Brandwonden Thermisch (2/2)")
    
    # Chemische brandwonden
    add_two_column_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "⚗️ Chemische Brandwonden — H₂SO₄ vs NaOH",
        "🧪 H₂SO₄ (Zwavelzuur)",
        ["H314: Veroorzaakt ernstige huidbrandwonden",
         "Spoelen: MINIMAAL 30 minuten met veel water",
         "GEEN neutraliseren met base! (exotherme reactie)",
         "Kleding: Uittrekken MAAR niet over hoofd als bevlekt",
         "Oogcontact: Spoelen 30 min, direct naar oogarts"],
        "🧪 NaOH (Natriumhydroxide)",
        ["H314: Veroorzaakt ernstige huidbrandwonden",
         "Spoelen: MINIMAAL 30 minuten met veel water",
         "GEEN neutraliseren met zuur! (exotherme reactie)",
         "NaOH dringt DIEPER door dan zuren — langer spoelen!",
         "Oogcontact: Spoelen 30+ min, LET OP: corneaschade risico"],
        subtitle="Theorie — Chemische Brandwonden (1/2)")
    
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "⚗️ Chemische Brandwonden — Phoenix Metals Protocol",
        ["Locatie oogdouches: Bij elke H₂SO₄/NaOH werkplek — 15 seconden bereikbaar",
         "Nooddouches: Verwerkingshal + opslagruimte — volledige lichaamsspoeling",
         "Procedure: 1) Spoelen (30 min) → 2) Kleding verwijderen → 3) Doorgaan met spoelen → 4) 112 bellen",
         "Valkuil: 'Even kijken hoe erg het is' → NIET kijken, DIRECT spoelen!",
         "V₂O₅ huidcontact: Spoelen met water + zeep, FFP3 bescherming bij stof",
         "Documentatie: Elke chemische blootstelling RAPPORTEREN aan HSEQ"],
        subtitle="Theorie — Chemische Brandwonden (2/2)")
    
    # Cyclomethicone
    add_bullet_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "💊 Stompenwonden & Cyclomethicone",
        ["Stompenwonden: Veroorzaakt door vallende objecten, botsingen met apparatuur",
         "Phoenix Metals: Zware materialen (vanadium, staalslakken) → risico op crush-letsel",
         "Eerste hulp: Koelen (ijs in doek), niet doorprikken blaren, verbinden",
         "Cyclomethicone: Gebruikt als beschermende laag bij wondbehandeling (industriel eerste hulp)",
         "BIJ TWIJFL: Altijd 112 bellen — inwendige bloeding niet zichtbaar!"],
        subtitle="Theorie — Stompenwonden (1/1)")
    
    # Alarmering
    add_flowchart_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📞 Alarmeringsprocedure bij Medisch Nood",
        ["Ontdek\nslachtoffer", "Zelf veilig?\n(PBM's!)", "Bel 112 +\nintern noodnr", "Start DRSABCD", "Wacht ambulance\n+ rapporteer"],
        subtitle="Theorie — Alarmering (1/1)")
    
    # Praktijkoefeningen
    add_table_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "🏋️ Praktijkoefeningen — Overzicht",
        ["Oefening", "Duur", "Wat leer je?", "Frequentie"],
        [["Reanimatie oefenpop", "15 min", "Borstcompressies + beademing (30:2)", "Jaarlijks"],
         ["AED scenario", "10 min", "AED bedienen + combinatie met reanimatie", "Jaarlijks"],
         ["Stabiele zijligging", "10 min", "Correct uitvoeren op collega/oefenpop", "Jaarlijks"],
         ["Chemische eerste hulp", "15 min", "Spoelen bij H₂SO₄/NaOH (simulatie)", "Jaarlijks"],
         ["Volledig scenario", "30 min", "Combinatie: alarm + DRSABCD + AED + rapportage", "Jaarlijks"]],
        subtitle="Praktijkoefeningen")
    
    # Samenvatting
    add_summary_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📋 Samenvatting — Key Takeaways",
        ["DRSABCD: Danger → Response → Send for help → Airway → Breathing → CPR → Defibrillation",
         "Reanimatie: 30 compressies + 2 beademingen, 100-120/min, 5-6 cm diep",
         "AED: Aanzetten, elektroden plakken, instructies volgen, NIET AANRAKEN bij analyse/schok",
         "Brandwonden: 20 min koelen (thermisch), 30 min spoelen (chemisch), GEEN zalven",
         "Chemisch H₂SO₄/NaOH: ALLEEN spoelen met water, NIET neutraliseren!",
         "Altijd eerst VEILIGHEID CHECKEN — dode BHV'er helpt niemand"],
        subtitle="Samenvatting")
    
    add_quiz_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📋 Kennistoets",
        ["Wat betekent elke letter in DRSABCD?",
         "Hoeveel borstcompressies en beademingen geef je per cyclus?",
         "Waarom mag je H₂SO₄-brandwonden NIET neutraliseren met een base?",
         "Wanneer plaats je iemand in stabiele zijligging?",
         "Bij een AED: waar plak je de elektroden precies?",
         "Hoe lang koel je een thermische brandwond minimaal?",
         "Wat is je eerste actie bij een persoon onder stroom?",
         "Hoe controleer je de ademhaling (B in DRSABCD)?",
         "Waarom is spoelen bij NaOH minstens 30 minuten (en niet 10)?",
         "Leg uit waarom een AED NIET in een ATEX-zone gebruikt mag worden"],
        subtitle="Kennistoets")
    
    add_references_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📚 Bronverwijzingen",
        ["NRR (Nederlandse Reanimatie Raad) — Richtlijnen Basisreanimatie 2021",
         "European Resuscitation Council (ERC) — Guidelines 2021",
         "Arbobesluit, Artikel 2.17 — Bedrijfshulpverlening",
         "SDS H₂SO₄ (CAS 7664-93-9) — Sectie 4: Eerstehulpmaatregelen",
         "SDS NaOH (CAS 1310-73-2) — Sectie 4: Eerstehulpmaatregelen",
         "SDS V₂O₅ (CAS 1314-62-1) — Sectie 4: Eerstehulpmaatregelen",
         "NEN 4003 — Inhoud eerste hulp kits",
         "Hartstichting — Cijfers hartstilstand Nederland 2023"])
    
    add_info_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "✅ TierVerify — Verificatielog",
        ["Document: PM_EL_T02_BHV_+_AED_Training_Presentatie_v1.1.pptx",
         "Bronverwijzingen: [1]-[8] gecontroleerd ✓",
         "Phoenix Metals context: Verwerkt in alle theorieblokken ✓",
         "JvG branding: Kleurenpalet, lettertype, footer aanwezig ✓",
         "Didactische structuur: Cover → Leerdoelen → Context → Theorie → Samenvatting → Toets ✓",
         "Status: GOEDGEKEURD voor gebruik"])
    
    path = os.path.join(OUTPUT_DIR, "PM_EL_T02_BHV_+_AED_Training_Presentatie_v1.1.pptx")
    prs.save(path)
    print(f"✅ T02 PPTX saved: {path}")

# ============================================================
# T03: Brandbestrijding
# ============================================================
def gen_T03():
    prs = create_prs()
    
    add_cover_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "Brandbestrijding Training",
        "Theorie en praktijk voor adequaat brandbestrijdingshandelen\nPhoenix Metals B.V.", "TR-301-03 | Versie 1.1 | April 2026")
    
    add_info_slide(prs.slides.add_slide(prs.slide_layouts[6]),
        "📋 Documentinformatie",
        ["Project: Phoenix Metals B.V. — Veiligheidsmanagement Systeem",
         "Training: Brandbestrijding",
         "Code: TR-301-03 | Versie: 1.1 | Auteur: JvG Consultancy",
         "Datum: April 2026 | Status: Definitief",
         "Doelgroep: Alle medewerkers (BH