#!/usr/bin/env python3
"""
PGS 15:2025 Phoenix Metals — DOCX Generator
Genereert 3 professionele DOCX bestanden (D1, D2, D3)
Met JvG Consultancy branding, logo, inhoudsopgave, bronverwijzingen, TierVerify.
"""

import os
from datetime import datetime
from docx import Document
from docx.shared import Cm, Inches, Pt, RGBColor, Emu
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.enum.section import WD_ORIENT
from docx.oxml.ns import qn, nsdecls
from docx.oxml import parse_xml

# ── Config ───────────────────────────────────────────────────────────────────
LOGO_PATH = "/root/projects/jg/assets/branding/jvg-consultancy-logo.png"
OUT_DIR   = "/root/projects/jg/2026-pgs15-phoenix-metals/deliverables/docx"
DATE_STR  = "6 mei 2026"
VERSION   = "2.0"
AUTHOR    = "JvG Consultancy"
FOOTER_TEXT = "JvG Consultancy | Safety • Governance • Advisory | © 2026"
PRIMARY_COLOR = RGBColor(0x00, 0x33, 0x66)
TEXT_COLOR     = RGBColor(0x1F, 0x29, 0x37)
BORDER_COLOR  = "E5E7EB"

ADR_STOFFEN = [
    {"stof":"Sulfuric acid 25%","cas":"7664-93-9","adr":"8","vg":"II","hzin":"H290, H314, H318","ondergrens":"250 kg","niveau":"Basis"},
    {"stof":"Hydrogen peroxide 30%","cas":"7722-84-1","adr":"5.1","vg":"II","hzin":"H302, H332, H318","ondergrens":"50 kg","niveau":"C"},
    {"stof":"Sodium persulfate","cas":"7775-27-1","adr":"5.1","vg":"III","hzin":"H272, H302, H315, H317, H319, H334, H335","ondergrens":"50 kg","niveau":"C"},
    {"stof":"Hydrochloric acid 20%","cas":"7647-01-0","adr":"8","vg":"II","hzin":"H290, H315, H319, H335","ondergrens":"250 kg","niveau":"Basis"},
    {"stof":"Sodium metavanadate solution","cas":"13718-26-8","adr":"6.1","vg":"III","hzin":"H301, H332, H319, H361fd, H372, H411","ondergrens":"1 kg*","niveau":"C"},
    {"stof":"Sodium aluminate solution","cas":"1302-42-7","adr":"8","vg":"III","hzin":"H314, H318","ondergrens":"250 kg","niveau":"Basis"},
    {"stof":"Vanadium pentoxide","cas":"1314-62-1","adr":"6.1","vg":"III","hzin":"H301, H318, H330, H335, H341, H350, H361fd, H362, H372, H411","ondergrens":"1 kg*","niveau":"C"},
    {"stof":"Vanadium electrolyte","cas":"7664-93-9/13701-70-7/27774-13-6","adr":"8","vg":"II","hzin":"H290, H302, H314, H318, H361, H401, H370, H335, H372","ondergrens":"25 kg","niveau":"Basis"},
]

CLP_STOFFEN = [
    {"stof":"Steel slag powder","cas":"65996-71-6","hzin":"H315, H318, H335, H372","risico":"STOT RE, Huid/oog"},
    {"stof":"Trisodium orthovanadate","cas":"13721-39-6","hzin":"H302, H312, H332, H315, H319","risico":"Acuut Tox 4"},
    {"stof":"Manganese(IV) oxide","cas":"1313-13-9","hzin":"H302, H332, H373","risico":"STOT RE 2"},
    {"stof":"Sodium phosphate","cas":"7601-54-9","hzin":"H315, H319, H335","risico":"Huid/oog"},
]

BUITEN_SCOPE = [
    "Calcium sulfate silica (mengsel)","Sodium sulfate decahydrate",
    "Calcium hydroxide","Silica (precipitated)","Iron oxide",
    "Magnesium hydroxide","Sodium hydroxide oplossing <5%"
]

os.makedirs(OUT_DIR, exist_ok=True)

# ── Helpers ──────────────────────────────────────────────────────────────────

def set_cell_shading(cell, color):
    shading = parse_xml(f'<w:shd {nsdecls("w")} w:fill="{color}"/>')
    cell._tc.get_or_add_tcPr().append(shading)

def set_cell_border(cell, **kwargs):
    tc = cell._tc
    tcPr = tc.get_or_add_tcPr()
    tcBorders = parse_xml(f'<w:tcBorders {nsdecls("w")}></w:tcBorders>')
    for edge, val in kwargs.items():
        element = parse_xml(
            f'<w:{edge} {nsdecls("w")} w:val="{val.get("val","single")}" '
            f'w:sz="{val.get("sz","4")}" w:space="0" w:color="{val.get("color",BORDER_COLOR)}"/>'
        )
        tcBorders.append(element)
    tcPr.append(tcBorders)

def add_header_with_logo(doc):
    section = doc.sections[0]
    header = section.header
    header.is_linked_to_previous = False
    p = header.paragraphs[0] if header.paragraphs else header.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.LEFT
    if os.path.exists(LOGO_PATH):
        run = p.add_run()
        run.add_picture(LOGO_PATH, width=Cm(2.0), height=Cm(1.8))
    # company name next to logo
    run2 = p.add_run("  JvG Consultancy")
    run2.font.size = Pt(14)
    run2.font.color.rgb = PRIMARY_COLOR
    run2.font.bold = True
    run2.font.name = "Calibri"
    # line under header
    p2 = header.add_paragraph()
    pBdr = parse_xml(
        f'<w:pBdr {nsdecls("w")}>'
        f'  <w:bottom w:val="single" w:sz="6" w:space="1" w:color="003366"/>'
        f'</w:pBdr>'
    )
    p2._p.get_or_add_pPr().append(pBdr)

def add_footer(doc):
    section = doc.sections[0]
    footer = section.footer
    footer.is_linked_to_previous = False
    p = footer.paragraphs[0] if footer.paragraphs else footer.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = p.add_run(FOOTER_TEXT)
    run.font.size = Pt(8)
    run.font.color.rgb = RGBColor(0x6B, 0x72, 0x80)
    run.font.name = "Calibri"

def add_doc_header_table(doc, project, doc_type, status="Definitief"):
    table = doc.add_table(rows=3, cols=4)
    table.alignment = WD_TABLE_ALIGNMENT.LEFT
    table.style = 'Table Grid'
    cells = [
        ("Project", project, "Type", doc_type),
    ]
    row0 = table.rows[0]
    for i, txt in enumerate(["Project", project, "Type", doc_type]):
        row0.cells[i].text = ""
        p = row0.cells[i].paragraphs[0]
        run = p.add_run(txt)
        run.font.size = Pt(10)
        run.font.name = "Calibri"
        if i % 2 == 0:
            run.font.bold = True
            run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
            set_cell_shading(row0.cells[i], "003366")
        else:
            run.font.color.rgb = TEXT_COLOR

    row1 = table.rows[1]
    for i, txt in enumerate(["Auteur", AUTHOR, "Versie", VERSION]):
        row1.cells[i].text = ""
        p = row1.cells[i].paragraphs[0]
        run = p.add_run(txt)
        run.font.size = Pt(10)
        run.font.name = "Calibri"
        if i % 2 == 0:
            run.font.bold = True
            run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
            set_cell_shading(row1.cells[i], "003366")
        else:
            run.font.color.rgb = TEXT_COLOR

    row2 = table.rows[2]
    for i, txt in enumerate(["Datum", DATE_STR, "Status", status]):
        row2.cells[i].text = ""
        p = row2.cells[i].paragraphs[0]
        run = p.add_run(txt)
        run.font.size = Pt(10)
        run.font.name = "Calibri"
        if i % 2 == 0:
            run.font.bold = True
            run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
            set_cell_shading(row2.cells[i], "003366")
        else:
            run.font.color.rgb = TEXT_COLOR
    doc.add_paragraph()

def add_toc(doc, sections_list):
    p = doc.add_paragraph()
    run = p.add_run("INHOUDSOPGAVE")
    run.font.size = Pt(14)
    run.font.bold = True
    run.font.color.rgb = PRIMARY_COLOR
    run.font.name = "Calibri"
    for num, title in sections_list:
        p2 = doc.add_paragraph()
        run2 = p2.add_run(f"{num}    {title}")
        run2.font.size = Pt(11)
        run2.font.name = "Calibri"
        run2.font.color.rgb = TEXT_COLOR
    doc.add_page_break()

def h1(doc, text):
    p = doc.add_heading(text, level=1)
    for run in p.runs:
        run.font.color.rgb = PRIMARY_COLOR
        run.font.name = "Calibri"
        run.font.size = Pt(16)

def h2(doc, text):
    p = doc.add_heading(text, level=2)
    for run in p.runs:
        run.font.color.rgb = PRIMARY_COLOR
        run.font.name = "Calibri"
        run.font.size = Pt(13)

def h3(doc, text):
    p = doc.add_heading(text, level=3)
    for run in p.runs:
        run.font.color.rgb = PRIMARY_COLOR
        run.font.name = "Calibri"
        run.font.size = Pt(11)

def body(doc, text):
    p = doc.add_paragraph()
    run = p.add_run(text)
    run.font.size = Pt(11)
    run.font.name = "Calibri"
    run.font.color.rgb = TEXT_COLOR
    return p

def body_bold(doc, text):
    p = doc.add_paragraph()
    run = p.add_run(text)
    run.font.size = Pt(11)
    run.font.name = "Calibri"
    run.font.color.rgb = TEXT_COLOR
    run.font.bold = True
    return p

def bullet(doc, text, level=0):
    p = doc.add_paragraph(style='List Bullet')
    p.clear()
    run = p.add_run(text)
    run.font.size = Pt(11)
    run.font.name = "Calibri"
    run.font.color.rgb = TEXT_COLOR
    if level > 0:
        p.paragraph_format.left_indent = Cm(1.5 * level)

def make_table(doc, headers, rows, col_widths=None):
    table = doc.add_table(rows=1+len(rows), cols=len(headers))
    table.style = 'Table Grid'
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    # Header row
    for i, h in enumerate(headers):
        cell = table.rows[0].cells[i]
        cell.text = ""
        p = cell.paragraphs[0]
        run = p.add_run(h)
        run.font.size = Pt(9)
        run.font.bold = True
        run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
        run.font.name = "Calibri"
        set_cell_shading(cell, "003366")
    # Data rows
    for ri, row_data in enumerate(rows):
        for ci, val in enumerate(row_data):
            cell = table.rows[ri+1].cells[ci]
            cell.text = ""
            p = cell.paragraphs[0]
            run = p.add_run(str(val))
            run.font.size = Pt(9)
            run.font.name = "Calibri"
            run.font.color.rgb = TEXT_COLOR
            if ri % 2 == 1:
                set_cell_shading(cell, "F0F4F8")
    doc.add_paragraph()
    return table

def add_references(doc, refs):
    h2(doc, "Bronverwijzingen")
    for i, ref in enumerate(refs, 1):
        body(doc, f"[{i}] {ref}")

def add_tier_verify(doc, checks):
    h2(doc, "TierVerify Log")
    table = doc.add_table(rows=1+len(checks), cols=4)
    table.style = 'Table Grid'
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    for i, h in enumerate(["Check", "Bron", "Status", "Datum"]):
        cell = table.rows[0].cells[i]
        cell.text = ""
        p = cell.paragraphs[0]
        run = p.add_run(h)
        run.font.size = Pt(9)
        run.font.bold = True
        run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
        run.font.name = "Calibri"
        set_cell_shading(cell, "003366")
    for ri, (chk, bron, status) in enumerate(checks):
        for ci, val in enumerate([chk, bron, status, DATE_STR]):
            cell = table.rows[ri+1].cells[ci]
            cell.text = ""
            p = cell.paragraphs[0]
            run = p.add_run(val)
            run.font.size = Pt(9)
            run.font.name = "Calibri"
            run.font.color.rgb = TEXT_COLOR
            if status == "✅ PASS":
                set_cell_shading(table.rows[ri+1].cells[2], "D4EDDA")
            elif status == "⚠️ REVIEW":
                set_cell_shading(table.rows[ri+1].cells[2], "FFF3CD")

# ══════════════════════════════════════════════════════════════════════════════
#  D1 — Kennisdossier
# ══════════════════════════════════════════════════════════════════════════════

def generate_d1():
    doc = Document()
    style = doc.styles['Normal']
    style.font.name = 'Calibri'
    style.font.size = Pt(11)
    style.font.color.rgb = TEXT_COLOR

    add_header_with_logo(doc)
    add_footer(doc)
    add_doc_header_table(doc, "Phoenix Metals Pilot Plant — PGS 15:2025", "Kennisdossier (D1)")

    # Title
    p = doc.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = p.add_run("PGS 15:2025 KENNISDOSSIER\nPhoenix Metals Pilot Plant Slag Chemicals")
    run.font.size = Pt(18)
    run.font.bold = True
    run.font.color.rgb = PRIMARY_COLOR
    run.font.name = "Calibri"

    sections = [
        ("1","Inleiding en doel"),
        ("2","Toepassingsgebied en referentiekader"),
        ("3","Wettelijk kader PGS 15:2025"),
        ("4","Definities en afkortingen"),
        ("5","Stoffeninventaris — ADR-geclassificeerd (8 stoffen)"),
        ("6","Stoffeninventaris — CLP-only (4 stoffen)"),
        ("7","Buiten scope stoffen (7 stoffen)"),
        ("8","ADR-klassen en verpakkingsgroepen"),
        ("9","H-zinnen analyse per stofgroep"),
        ("10","Compatibiliteitsmatrix (PGS 15 Tabel 9)"),
        ("11","Scheidingsgroepen — SG1, SG2, SG5"),
        ("12","Veiligheidsniveaus — Bepaling en classificatie"),
        ("13","Kritieke risico's — V₂O₅ en CMR-stoffen"),
        ("14","Opslagscenario — 3-vakken indeling"),
        ("15","Opschalingscriteria en niveau-overgangen"),
        ("16","QA Validatie — Scanner resultaten"),
        ("17","Bronverwijzingen"),
        ("18","TierVerify Log"),
    ]
    add_toc(doc, sections)

    # 1
    h1(doc, "1. Inleiding en doel")
    body(doc, "Dit kennisdossier documenteert de PGS 15:2025 compliance analyse voor de Phoenix Metals Pilot Plant inzake de opslag van gevaarlijke stoffen afkomstig van slag chemical processing [1]. Het doel is om een volledig inzicht te geven in de toepasselijke regelgeving, stoffeninventaris, compatibiliteitseisen en veiligheidsniveaus conform de Publicatiereeks Gevaarlijke Stoffen.")
    body(doc, "Het dossier fungeert als basiskennisdocument voor alle verdere HSEQ-documentatie, werkinstructies en veiligheidsinformatie-documentatie binnen het Phoenix Metals project.")

    # 2
    h1(doc, "2. Toepassingsgebied en referentiekader")
    body(doc, "Dit dossier is van toepassing op de opslag van gevaarlijke stoffen bij de Phoenix Metals Pilot Plant, waar slakaftarde chemicaliën worden verwerkt tot vanadium-elektrolyt en bijproducten [1]. De Pilot Plant behandelt 19 unieke chemicaliën, waarvan 8 ADR-geclassificeerd zijn en daarmee binnen de scope van PGS 15:2025 vallen.")
    body(doc, "Referentiekader: PGS 15:2025 v1.0 (januari 2025), Publicatie 565. Er zijn geen errata gepubliceerd op publicatiereeksgevaarlijkestoffen.nl voor deze versie [1].")

    # 3
    h1(doc, "3. Wettelijk kader PGS 15:2025")
    body(doc, "PGS 15 is de branche-richtlijn voor de opslag van gevaarlijke stoffen in verpakkingen en omhulsels. De richtlijn is geïmplementeerd onder het Besluit activiteiten leefomgeving (Bal) en het Besluit bouwwerken leefomgeving (Bbl) per 1 januari 2025 [1].")
    h2(doc, "3.1 Relatie met andere regelgeving")
    bullet(doc, "ADR (Accord européen relatif au transport international des marchandises Dangereuses par Route) — classificatie van stoffen [2]")
    bullet(doc, "CLP (Classification, Labelling and Packaging) — EU Verordening 1272/2008 [3]")
    bullet(doc, "Arbowetgeving — Arbobesluit art. 4.1c en 4.1d [4]")
    bullet(doc, "ARES (Algemene Regels gevaarlijke stoffen) — BRZO 2015 waar van toepassing [5]")
    h2(doc, "3.2 Status PGS 15:2025")
    body(doc, "PGS 15:2025 v1.0 is de actuele versie sinds januari 2025. Publicatie 565 bevat de volledige richtlijntekst inclusief bijlagen. Er zijn geen errata gepubliceerd [1].")

    # 4
    h1(doc, "4. Definities en afkortingen")
    defs = [
        ("PGS","Publicatiereeks Gevaarlijke Stoffen"),
        ("ADR","Accord européen relatif au transport international des marchandises Dangereuses par Route"),
        ("CLP","Classification, Labelling and Packaging (EG 1272/2008)"),
        ("SDS","Safety Data Sheet (Veiligheidsdatablad)"),
        ("CMR","Carcinogeen, Mutageen, Reproductietoxisch"),
        ("STOT","Specific Target Organ Toxicity"),
        ("SG","Scheidingsgroep"),
        ("H-zin","Gevarenaanduiding (Hazard statement)"),
        ("P-zin","Voorzorgsmaatregel (Precautionary statement)"),
        ("VG","Verpakkingsgroep (I, II, III)"),
        ("BAL","Besluit activiteiten leefomgeving"),
        ("BBL","Besluit bouwwerken leefomgeving"),
    ]
    make_table(doc, ["Afkorting","Definitie"], defs)

    # 5
    h1(doc, "5. Stoffeninventaris — ADR-geclassificeerd (8 stoffen)")
    body(doc, "De volgende 8 stoffen zijn ADR-geclassificeerd en vallen binnen de scope van PGS 15:2025. Per stof is het CAS-nummer, ADR-klasse, verpakkingsgroep, H-zinnen, toepasselijke ondergrens en veiligheidsniveau bepaald [1][3].")
    rows = [[s["stof"],s["cas"],s["adr"],s["vg"],s["hzin"],s["ondergrens"],s["niveau"]] for s in ADR_STOFFEN]
    make_table(doc, ["Stof","CAS","ADR","VG","H-zinnen","Ondergrens","VNiveau"], rows)
    body(doc, "* Ondergrens 1 kg i.v.m. Acute Tox (H330/H301) + CMR-classificatie. Deze stoffen zijn vrijgesteld tot maximaal de testhoeveelheid, maar bij overschrijding geldt volledig PGS 15-regime [1].")

    # 6
    h1(doc, "6. Stoffeninventaris — CLP-only (4 stoffen)")
    body(doc, "De volgende 4 stoffen zijn uitsluitend CLP-geclassificeerd (geen ADR-klasse) en vallen onder het basisveiligheidsniveau van PGS 15:2025 [1][3].")
    rows = [[s["stof"],s["cas"],s["hzin"],s["risico"]] for s in CLP_STOFFEN]
    make_table(doc, ["Stof","CAS","H-zinnen","Primair risico"], rows)

    # 7
    h1(doc, "7. Buiten scope stoffen (7 stoffen)")
    body(doc, "De volgende 7 stoffen zijn niet ADR-geclassificeerd en hebben geen CLP-gevarenaanduidingen die onder PGS 15 vallen. Deze stoffen vereisen geen PGS 15-specifieke opslagmaatregelen [1].")
    for s in BUITEN_SCOPE:
        bullet(doc, s)
    body(doc, "Deze stoffen dienen wel te worden opgeslagen volgens algemene arbovoorschriften en leveranciersinstructies.")

    # 8
    h1(doc, "8. ADR-klassen en verpakkingsgroepen")
    h2(doc, "8.1 ADR-klassen in de inventaris")
    body(doc, "De Pilot Plant inventaris omvat drie ADR-klassen [2]:")
    bullet(doc, "ADR 5.1 (Brandbevorderend): H₂O₂ 30%, Sodium persulfate")
    bullet(doc, "ADR 6.1 (Toxisch): Sodium metavanadate oplossing, Vanadium pentoxide")
    bullet(doc, "ADR 8 (Corrosief): H₂SO₄ 25%, HCl 20%, Na-aluminaat oplossing, Vanadium electrolyt")
    h2(doc, "8.2 Verpakkingsgroepen")
    body(doc, "De verdeling over verpakkingsgroepen is als volgt [2]:")
    bullet(doc, "VG II (hoog gevaar): Sulfuric acid 25%, H₂O₂ 30%, HCl 20%, Vanadium electrolyt")
    bullet(doc, "VG III (laag gevaar): Sodium persulfate, Na-metavanadate, Na-aluminaat, V₂O₅")
    h2(doc, "8.3 Implicaties voor opslag")
    body(doc, "VG II-stoffen vereisen strengere verpakkings- en opslageisen dan VG III-stoffen. In combinatie met de ADR-klasse bepaalt de verpakkingsgroep het uiteindelijke veiligheidsniveau [1].")

    # 9
    h1(doc, "9. H-zinnen analyse per stofgroep")
    h2(doc, "9.1 Meest frequente H-zinnen")
    body(doc, "Analyse van de H-zinnen over alle 19 stoffen toont de volgende prevalentie [3]:")
    bullet(doc, "H314/H318 (Huid/oog corrosie/irritatie): 10 stoffen")
    bullet(doc, "H315/H319 (Huid/oog irritatie): 6 stoffen")
    bullet(doc, "H335 (Irritant ademhalingsstelsel): 5 stoffen")
    bullet(doc, "H302 (Oraal acuut tox 4): 5 stoffen")
    bullet(doc, "H332 (Inhalatief acuut tox 4): 3 stoffen")
    bullet(doc, "H372/H373 (STOT herhaalde blootstelling): 4 stoffen")
    h2(doc, "9.2 CMR H-zinnen (kritiek)")
    body(doc, "De volgende CMR H-zinnen zijn aanwezig in de inventaris [3]:")
    bullet(doc, "H350 (Carc. 1B): V₂O₅ — KANKERVERWEKKEND")
    bullet(doc, "H341 (Mut. 2): V₂O₅ — VERMOEDELIJK MUTAGEEN")
    bullet(doc, "H361fd (Repr. 2): V₂O₅, Na-metavanadate — VERMOEDELIJK REPRODUCTIOTOXISCH")
    bullet(doc, "H362 (Lact.): V₂O₅ — KAN schade toebrengen aan borstgevoede kinderen")
    bullet(doc, "H330 (Acuut Tox 1): V₂O₅ — DODELIJK BIJ INHALATIE")
    bullet(doc, "H370 (STOT SE 1): Vanadium electrolyt — SCHADE AAN ORGANEN")
    h2(doc, "9.3 Milieu H-zinnen")
    bullet(doc, "H411 (Chronisch aquatisch tox 2): Na-metavanadate, V₂O₅")
    bullet(doc, "H401 (Acuut aquatisch tox 2): Vanadium electrolyt")

    # 10
    h1(doc, "10. Compatibiliteitsmatrix (PGS 15 Tabel 9)")
    body(doc, "De compatibiliteitsmatrix bepaalt welke stofcombinaties gezamenlijk mogen worden opgeslagen en welke scheiding vereist is. Dit is afgeleid uit PGS 15:2025 Tabel 9 [1].")
    matrix = [
        ["ADR 5.1","—","V (aparte vakken)","B (gescheiden)","—"],
        ["ADR 6.1","V","—","BA (apart compartiment)","—"],
        ["ADR 8","B","BA","—","—"],
        ["Geen ADR","—","—","—","Vrij"],
    ]
    make_table(doc, ["","ADR 5.1","ADR 6.1","ADR 8","Geen ADR"], matrix)
    body(doc, "Legenda:")
    bullet(doc, "V = Verplicht aparte vakken (fysieke scheiding door wanden)")
    bullet(doc, "B = Gescheiden tenzij beoordeeld (risicobeoordeling vereist)")
    bullet(doc, "BA = Apart brandcompartiment (30 min brandwerend) of minimaal 5 meter zone")

    # 11
    h1(doc, "11. Scheidingsgroepen — SG1, SG2, SG5")
    body(doc, "Op basis van de ADR-klassen en chemische eigenschappen worden drie scheidingsgroepen onderscheiden [1]:")
    h2(doc, "11.1 SG2 — Brandbevorderend")
    bullet(doc, "H₂O₂ 30% (ADR 5.1, VG II)")
    bullet(doc, "Sodium persulfate (ADR 5.1, VG III)")
    body(doc, "Deze stoffen mogen NIET samen met brandbare stoffen worden opgeslagen. Scheiding van SG1 en SG5 is verplicht [1].")
    h2(doc, "11.2 SG1 — Toxisch/CMR")
    bullet(doc, "Sodium metavanadate oplossing (ADR 6.1, VG III)")
    bullet(doc, "Vanadium pentoxide (ADR 6.1, VG III)")
    body(doc, "Deze stoffen vereisen aparte opslag vanwege acute toxiciteit en CMR-classificatie. Verplicht in apart compartiment gescheiden van SG2 en SG5 [1].")
    h2(doc, "11.3 SG5 — Corrosief")
    bullet(doc, "H₂SO₄ 25% (ADR 8, VG II)")
    bullet(doc, "HCl 20% (ADR 8, VG II)")
    bullet(doc, "Sodium aluminate solution (ADR 8, VG III)")
    bullet(doc, "Vanadium electrolyte (ADR 8, VG II)")
    body(doc, "Corrosieve stoffen mogen gezamenlijk in één vak worden opgeslagen, mits voldoende chemische compatibiliteit is aangetoond [1].")

    # 12
    h1(doc, "12. Veiligheidsniveaus — Bepaling en classificatie")
    h2(doc, "12.1 Niveau C-stoffen (4 stoffen)")
    body(doc, "Het veiligheidsniveau C geldt voor stoffen met verhoogde risico's die aanvullende maatregelen vereisen boven het basisniveau [1]:")
    bullet(doc, "H₂O₂ 30% — Brandbevorderend, reactief")
    bullet(doc, "Sodium persulfate — Brandbevorderend, oxidator")
    bullet(doc, "Na-metavanadate oplossing — Acuut Tox 3, Repr. 2")
    bullet(doc, "V₂O₅ — Carc. 1B, Acuut Tox 1, Mut. 2, Repr. 2")
    h2(doc, "12.2 Basisniveau-stoffen (4 stoffen)")
    bullet(doc, "H₂SO₄ 25% — Corrosief")
    bullet(doc, "HCl 20% — Corrosief")
    bullet(doc, "Na-aluminaat oplossing — Corrosief")
    bullet(doc, "Vanadium electrolyt — Corrosief + STOT SE 1")
    h2(doc, "12.3 Geen A-niveau van toepassing")
    body(doc, "Bij de huidige testhoeveelheden (< 10 ton per stof) is veiligheidsniveau A niet van toepassing [1]. Niveau A geldt pas bij opschaling > 20 ton voor ADR 6.1-stoffen.")

    # 13
    h1(doc, "13. Kritieke risico's — V₂O₅ en CMR-stoffen")
    h2(doc, "13.1 Vanadium pentoxide (V₂O₅)")
    body(doc, "V₂O₅ is de meest kritieke stof in de inventaris met de volgende classificaties [3]:")
    bullet(doc, "H350 — Carc. 1B: Kankerverwekkend (bewezen bij dieren, voldoende aanwijzingen bij mensen)")
    bullet(doc, "H330 — Acuut Tox 1: Dodelijk bij inhalatie")
    bullet(doc, "H341 — Mut. 2: Vermoedelijk mutageen")
    bullet(doc, "H361fd — Repr. 2: Vermoedelijk reproductietoxisch (vruchtbaarheid + ontwikkeling)")
    bullet(doc, "H362 — Lact.: Kan schade toebrengen aan borstgevoede kinderen")
    bullet(doc, "H372 — STOT RE 1: Schade aan organen bij herhaalde blootstelling")
    bullet(doc, "H301 — Acuut Tox 3: Toxisch bij inslikken")
    bullet(doc, "H318 — Veroorzaakt ernstig oogletsel")
    h2(doc, "13.2 Sodium metavanadate oplossing")
    bullet(doc, "H301 — Acuut Tox 3: Toxisch bij inslikken")
    bullet(doc, "H361fd — Repr. 2: Vermoedelijk reproductietoxisch")
    bullet(doc, "H411 — Chronisch aquatisch tox 2 (milieugevaar)")
    h2(doc, "13.3 Chemische incompatibiliteit: H₂O₂ + zuren")
    body(doc, "Waterstofperoxide (H₂O₂ 30%) is chemisch onverenigbaar met zuren (H₂SO₄, HCl). Menging kan leiden tot gevaarlijke reacties met zuurstofontwikkeling en hitteproductie [1][6]. Fysieke scheiding is daarom VERPLICHT.")
    h2(doc, "13.4 Vanadium electrolyt")
    body(doc, "Vanadium electrolyt combineert corrosieve eigenschappen (ADR 8) met CMR-risico's (H361) en STOT SE 1 (H370). Opslag vereist zowel corrosief- als CMR-maatregelen [1].")

    # 14
    h1(doc, "14. Opslagscenario — 3-vakken indeling")
    body(doc, "Op basis van de compatibiliteitsmatrix en scheidingsgroepen wordt een 3-vakken opslagindeling voorgesteld [1]:")
    h2(doc, "14.1 Vak 1 — Brandbevorderend (SG2)")
    bullet(doc, "H₂O₂ 30%")
    bullet(doc, "Sodium persulfate")
    body(doc, "Scheiding: Fysieke wand van minimaal brandwerend 30 minuten naar Vak 2 en Vak 3.")
    h2(doc, "14.2 Vak 2 — Toxisch/CMR (SG1)")
    bullet(doc, "Sodium metavanadate oplossing")
    bullet(doc, "V₂O₅")
    body(doc, "Scheiding: Apart brandcompartiment (BA) ten opzichte van Vak 3 (corrosief). Afgesloten toegang, ventilatie verplicht.")
    h2(doc, "14.3 Vak 3 — Corrosief (SG5)")
    bullet(doc, "H₂SO₄ 25%")
    bullet(doc, "HCl 20%")
    bullet(doc, "Sodium aluminate solution")
    bullet(doc, "Vanadium electrolyte")
    body(doc, "Corrosieve stoffen mogen gezamenlijk worden opgeslagen. Leistroom- en lekbakken verplicht.")
    h2(doc, "14.4 Overige stoffen")
    body(doc, "CLP-only stoffen en buiten-scope stoffen worden opgeslagen in een algemeen chemisch magazijn, gescheiden van de ADR-geclassificeerde vakken.")

    # 15
    h1(doc, "15. Opschalingscriteria en niveau-overgangen")
    body(doc, "De veiligheidsniveaus zijn afhankelijk van de opgeslagen hoeveelheden. Bij opschaling van de Pilot Plant gelden de volgende overgangen [1]:")
    rows = [
        ["Testhoeveelheden (< 10 ton)","Basisniveau / Niveau C","Huidige situatie"],
        ["> 10 ton (ADR 5.1, ADR 6.1)","Niveau B","Aanvullende constructieve eisen"],
        ["> 20 ton (ADR 6.1)","Niveau A","Volledig PGS 15-regime incl.Extern Veiligheidsrapport"],
    ]
    make_table(doc, ["Drempelwaarde","Veiligheidsniveau","Opmerking"], rows)

    # 16
    h1(doc, "16. QA Validatie — Scanner resultaten")
    body(doc, "De PGS15 Scanner Tool is getest met alle 8 Pilot Plant stoffen. Resultaten [1]:")
    bullet(doc, "8/8 veiligheidsniveaus MATCH tussen onafhankelijke analyse en scanner")
    bullet(doc, "12 scheidingconflicten correct gedetecteerd uit compatibiliteitsmatrix")
    bullet(doc, "Geen errata op PGS 15:2025 v1.0 (geverifieerd op publicatiereeksgevaarlijkestoffen.nl)")
    body(doc, "Conclusie: De scanner resultaten zijn consistent met de handmatige analyse. Het kennisdossier kan als betrouwbare basis dienen voor verdere HSEQ-documentatie.")

    # 17
    refs = [
        "PGS 15:2025 v1.0 — Publicatiereeks Gevaarlijke Stoffen, Publicatie 565, januari 2025. Beschikbaar via publicatiereeksgevaarlijkestoffen.nl",
        "ADR 2025 — European Agreement concerning the International Carriage of Dangerous Goods by Road, UN Economic Commission for Europe",
        "CLP Verordening (EG) Nr. 1272/2008 — Classification, Labelling and Packaging of Substances and Mixtures, Europese Commissie",
        "Arbobesluit — Besluit van 15 januari 1997, houdende maatregelen in het belang van de veiligheid, de gezondheid en het welzijn in verband met de arbeid",
        "BRMO / BRZO 2015 — Besluit risico's zware ongevallen 2015 (implementatie Seveso III-richtlijn)",
        "Veiligheidsdatabladen (SDS) van de betreffende stoffen — leveranciersinformatie",
    ]
    add_references(doc, refs)

    # 18
    checks = [
        ("ADR-classificatie 8 stoffen","PGS 15:2025 §4 + SDS","✅ PASS"),
        ("H-zinnen consistentie","CLP 1272/2008 + SDS","✅ PASS"),
        ("Compatibiliteitsmatrix Tabel 9","PGS 15:2025 Tabel 9","✅ PASS"),
        ("Veiligheidsniveaus 8/8 match","PGS15 Scanner Tool","✅ PASS"),
        ("12 scheidingconflicten","Compatibiliteitsmatrix","✅ PASS"),
        ("Geen errata PGS 15:2025 v1.0","publicatiereeksgevaarlijkestoffen.nl","✅ PASS"),
        ("V₂O₅ CMR-classificatie","SDS + CLP Annex VI","✅ PASS"),
        ("Opschalingscriteria","PGS 15:2025 §5","✅ PASS"),
    ]
    add_tier_verify(doc, checks)

    path = os.path.join(OUT_DIR, "PGS15_Kennisdossier_Phoenix_Metals_D1_v2.0.docx")
    doc.save(path)
    print(f"✅ D1 opgeslagen: {path}")
    return path

# ══════════════════════════════════════════════════════════════════════════════
#  D2 — VeiligWerken HSEQ
# ══════════════════════════════════════════════════════════════════════════════

def generate_d2():
    doc = Document()
    style = doc.styles['Normal']
    style.font.name = 'Calibri'
    style.font.size = Pt(11)
    style.font.color.rgb = TEXT_COLOR

    add_header_with_logo(doc)
    add_footer(doc)
    add_doc_header_table(doc, "Phoenix Metals Pilot Plant — PGS 15:2025", "HSEQ Werkinstructie (D2)")

    p = doc.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = p.add_run("PGS 15:2025 VEILIG WERKEN\nHSEQ Werkinstructie Phoenix Metals Pilot Plant")
    run.font.size = Pt(18)
    run.font.bold = True
    run.font.color.rgb = PRIMARY_COLOR
    run.font.name = "Calibri"

    sections = [
        ("1","Doel en toepassingsgebied"),
        ("2","Verantwoordelijkheden"),
        ("3","Algemene omgangsregels gevaarlijke stoffen"),
        ("4","Omgangsregels per stofgroep — SG2 Brandbevorderend"),
        ("5","Omgangsregels per stofgroep — SG1 Toxisch/CMR"),
        ("6","Omgangsregels per stofgroep — SG5 Corrosief"),
        ("7","PBM-eisen per activiteit"),
        ("8","V₂O₅ blootstellingsbeperking protocol"),
        ("9","Opslagregels — Algemeen"),
        ("10","Opslagregels — SG2 Brandbevorderend"),
        ("11","Opslagregels — SG1 Toxisch/CMR"),
        ("12","Opslagregels — SG5 Corrosief"),
        ("13","Noodprocedure — Algemene instructies"),
        ("14","Noodprocedure — Stofspecifieke maatregelen"),
        ("15","Dagelijkse inspectie checklist"),
        ("16","Training en instructie-eisen"),
        ("17","Bronverwijzingen"),
        ("18","TierVerify Log"),
    ]
    add_toc(doc, sections)

    # 1
    h1(doc, "1. Doel en toepassingsgebied")
    body(doc, "Deze HSEQ werkinstructie beschrijft de veilige werkwijze bij het omgaan met en opslaan van gevaarlijke stoffen in de Phoenix Metals Pilot Plant, conform PGS 15:2025 [1]. De instructie is bedoeld voor alle medewerkers en bezoekers die in aanraking komen met de 19 chemicaliën in de inventaris.")
    body(doc, "De werkinstructie omvat omgangsregels, persoonlijke beschermingsmiddelen (PBM), opslagregels, noodprocedures en inspectie-eisen.")

    # 2
    h1(doc, "2. Verantwoordelijkheden")
    h2(doc, "2.1 Directie / Plant Manager")
    bullet(doc, "Zorgdragen voor adequate voorzieningen en middelen voor veilig werken")
    bullet(doc, "Goedkeuring van risicobeoordelingen en werkvergunningen")
    bullet(doc, "Periodieke review van deze werkinstructie (minimaal jaarlijks)")
    h2(doc, "2.2 HSEQ-functionaris")
    bullet(doc, "Onderhoud en actualisatie van deze werkinstructie")
    bullet(doc, "Uitvoeren van risicobeoordelingen en inspecties")
    bullet(doc, "Instrueren en toetsen van medewerkers")
    h2(doc, "2.3 Medewerkers")
    bullet(doc, "Opvolgen van deze werkinstructie en aanvullende instructies")
    bullet(doc, "Gebruik van voorgeschreven PBM")
    bullet(doc, "Melden van onveilige situaties en incidenten")

    # 3
    h1(doc, "3. Algemene omgangsregels gevaarlijke stoffen")
    body(doc, "De volgende regels gelden voor ALLE stoffen in de inventaris, ongeacht classificatie [1][4]:")
    bullet(doc, "Raadpleeg altijd het SDS (Veiligheidsdatablad) vóór het werken met een stof")
    bullet(doc, "Eten, drinken en roken zijn verboden in de opslag- en werkruimten")
    bullet(doc, "Draag altijd de voorgeschreven PBM (zie §7)")
    bullet(doc, "Voorkom huid- en oogcontact — gebruik gesloten systemen waar mogelijk")
    bullet(doc, "Zorg voor adequate ventilatie (algemeen minimaal 3x luchtverversing per uur)")
    bullet(doc, "Label alle verpakkingen conform CLP-voorschriften [3]")
    bullet(doc, "Scheid onverenigbare stoffen conform compatibiliteitsmatrix (zie Kennisdossier D1 §10)")
    bullet(doc, "Beperk de voorraad in de werkruimte tot de hoeveelheid nodig voor één werkdag")
    bullet(doc, "Sluit verpakkingen direct na gebruik")
    bullet(doc, "Rapporteer lekkages of beschadigde verpakkingen onmiddellijk aan de HSEQ-functionaris")

    # 4
    h1(doc, "4. Omgangsregels per stofgroep — SG2 Brandbevorderend")
    body(doc, "SG2 omvat H₂O₂ 30% en Sodium persulfate [1].")
    h2(doc, "4.1 Waterstofperoxide 30%")
    bullet(doc, "VERBODEN contact met brandbare stoffen, organische materialen en metalen")
    bullet(doc, "Altijd in de originele donkere verpakking bewaren (lichtgevoelig)")
    bullet(doc, "Nooit in metalen containers overgieten (katalytische ontleding)")
    bullet(doc, "Bij verhitting: ontleding met zuurstofontwikkeling — explosiegevaar in afgesloten ruimten")
    bullet(doc, "Neutralisatie: met natriumthiosulfaat-oplossing onder roeren")
    h2(doc, "4.2 Sodium persulfate")
    bullet(doc, "Vermijd contact met brandbare stoffen en reducing agents")
    bullet(doc, "Stofvrij werken — gebruik stofafzuiging bij afwegen")
    bullet(doc, "Niet verwarmen boven 50°C — ontledingsrisico")
    bullet(doc, "Bij contact met vocht: langzame ontleding — bewaar droog")

    # 5
    h1(doc, "5. Omgangsregels per stofgroep — SG1 Toxisch/CMR")
    body(doc, "SG1 omvat Sodium metavanadate oplossing en Vanadium pentoxide (V₂O₅) [1].")
    body_bold(doc, "⚠️ VERHOOGDE VOORZICHTIGHEID VEREIST — CMR-STOFFEN")
    h2(doc, "5.1 Algemene SG1-regels")
    bullet(doc, "Werk alleen in gesloten systemen of onder afzuiging")
    bullet(doc, "Verboden te werken zonder geldig werkvergunningssysteem")
    bullet(doc, "Twee-persoons regel: nooit alleen werken met SG1-stoffen")
    bullet(doc, "Directe huid- en oogcontact VERBODEN — dubbele handschoenen")
    bullet(doc, "Na beëindigen werkzaamheden: verplichte wasprocedure (handen, gezicht, onderarmen)")
    h2(doc, "5.2 Vanadium pentoxide (V₂O₅) — Aanvullende regels")
    bullet(doc, "CARC. 1B (H350) — Kankerverwekkend: blootstelling MINIMALISEREN [3]")
    bullet(doc, "Acuut Tox 1 (H330) — Dodelijk bij inhalatie: ADEMHALINGSBESCHERMING VERPLICHT")
    bullet(doc, "Stofvrij werken — alle handelingen onder afzuiging of in glovebox")
    bullet(doc, "Bij overschrijding blootstellingslimiet: onmiddellijk stoppen en evacueren")
    bullet(doc, "Medische surveillance verplicht voor regelmatig blootgestelde werknemers")

    # 6
    h1(doc, "6. Omgangsregels per stofgroep — SG5 Corrosief")
    body(doc, "SG5 omvat H₂SO₄ 25%, HCl 20%, Na-aluminaat oplossing en Vanadium electrolyt [1].")
    h2(doc, "6.1 Algemene SG5-regels")
    bullet(doc, "Altijd zuur bij water toevoegen, NOOIT water bij zuur (exotherme reactie)")
    bullet(doc, "Gebruik bij voorkeur gesloten doseersystemen")
    bullet(doc, "Nooddouche en oogdouche binnen 10 seconden bereikbaar")
    bullet(doc, "Leistroom- en lekbakken bij alle corrosieve opslag")
    bullet(doc, "Bij Huidcontact: onmiddellijk 15 minuten spoelen met overvloedig water")
    h2(doc, "6.2 Vanadium electrolyt — Aanvullende regels")
    bullet(doc, "Combineert corrosief (ADR 8) met CMR (H361) en STOT SE 1 (H370)")
    bullet(doc, "Naast corrosief-maatregelen OOK CMR-protocollaire maatregelen toepassen")
    bullet(doc, "Biologische monitoring aanbevolen bij regelmatige blootstelling")

    # 7
    h1(doc, "7. PBM-eisen per activiteit")
    body(doc, "De volgende PBM zijn verplicht bij de aangegeven activiteiten [4]:")
    rows = [
        ["Algemeen magazijnwerk","Veiligheidsbril, veiligheidshandschoenen (nitril), veiligheidsschoenen S3","Alle stoffen"],
        ["Omgaan met SG5 (corrosief)","Veiligheidsbril, gezichtsscherm, zuurbestendige handschoenen (PVC), veiligheidsschoenen S3, kunststof schort","H₂SO₄, HCl, Na-aluminaat, V-elektrolyt"],
        ["Omgaan met SG2 (brandbevorderend)","Veiligheidsbril, nitril handschoenen, veiligheidsschoenen S3, katoenen werkbroek (synthetisch verboden)","H₂O₂, Na-persulfate"],
        ["Omgaan met SG1 (toxisch/CMR)","Veiligheidsbril, dubbele handschoenen, volledige overall, ademhalingsbescherming (FFP3 of P3), gezichtsscherm","V₂O₅, Na-metavanadate"],
        ["V₂O₅ afwegen/scheiden","Volledige P3-ademhalingsbescherming, chemicaliënbestendige overall, dubbele nitril handschoenen, gezichtsscherm, capuchon","V₂O₅"],
        ["Lekkage opruimen SG5","Veiligheidsbril, zuurbestendige handschoenen, veiligheidsschoenen, kunststof schort, indien dampen: halfmasker ABEK","H₂SO₄, HCl"],
        ["Lekkage opruimen SG1","Volledige bescherming: P3-filter, chemicaliënoverall, dubbele handschoenen, laarzen, gezichtsscherm","V₂O₅, Na-metavanadate"],
    ]
    make_table(doc, ["Activiteit","Verplichte PBM","Stof(fen)"], rows)

    # 8
    h1(doc, "8. V₂O₅ blootstellingsbeperking protocol")
    h2(doc, "8.1 Grenswaarden")
    body(doc, "Vanadium pentoxide heeft een extremely lage blootstellingslimiet [4]:")
    bullet(doc, "TGG-8u (time-weighted average): 0,025 mg/m³ (als V₂O₅ stof)")
    bullet(doc, "TGG-15min (korte-termijn): 0,075 mg/m³")
    body(doc, "Omdat V₂O₅ is geclassificeerd als Carc. 1B (H350), geldt het ALARA-principe: blootstelling zo laag als redelijkerwijs mogelijk [4].")
    h2(doc, "8.2 Blootstellingsbeperkende maatregelen")
    bullet(doc, "Volledig gesloten systeem voor alle omgang met V₂O₅-poeder")
    bullet(doc, "Lokale afzuiging met HEPA-filtratie (minimaal efficiëntie 99,97% bij 0,3 μm)")
    bullet(doc, "P3-ademhalingsbescherming bij alle handelingen buiten gesloten systeem")
    bullet(doc, "Regelmatige blootstellingsmeting (persoonlijke bemonstering)")
    bullet(doc, "Medische surveillance: baseline en periodiek longfunctieonderzoek")
    h2(doc, "8.3 Procedure bij overschrijding")
    body(doc, "Indien een blootstellingsmeting de grenswaarde overschrijdt [4]:")
    bullet(doc, "Onmiddellijk stoppen met de betreffende werkzaamheden")
    bullet(doc, "Werkruimte evacueren en afsluiten")
    bullet(doc, "HSEQ-functionaris informeren")
    bullet(doc, "Oorzaak analyseren en corrigerende maatregelen nemen")
    bullet(doc, "Hervatten pas na goedkeuring door HSEQ-functionaris")

    # 9
    h1(doc, "9. Opslagregels — Algemeen")
    body(doc, "De volgende algemene opslagregels gelden voor alle ADR-geclassificeerde stoffen [1]:")
    bullet(doc, "Opslag uitsluitend in de daartoe bestemde vakken (zie §10-§12)")
    bullet(doc, "Verpakkingen gesloten houden tenzij direct in gebruik")
    bullet(doc, "Etikettering conform CLP op alle verpakkingen zichtbaar")
    bullet(doc, "Maximale stapelhoogte: 2 meter (of conform leveranciersvoorschrift)")
    bullet(doc, "Voldoende loopruimte: minimaal 80 cm tussen opslagstellingen")
    bullet(doc, "Leistroom- en lekbakken: capaciteit minimaal 110% van grootste enkelvoudige verpakking")
    bullet(doc, "Temperatuurbeheersing: tussen 5°C en 25°C (tenzij anders voorgeschreven)")
    bullet(doc, "Verboden: voedsel, dranken, medicijnen en persoonlijke spullen in opslagruimten")

    # 10
    h1(doc, "10. Opslagregels — SG2 Brandbevorderend")
    body(doc, "Vak 1 — Brandbevorderende stoffen (ADR 5.1) [1]:")
    bullet(doc, "GESCHEIDEN houden van SG1 (toxisch) en SG5 (corrosief) — fysieke wand verplicht")
    bullet(doc, "Brandblusmiddelen: CO₂ en poeder in directe nabijheid")
    bullet(doc, "H₂O₂ 30% opslag in originele donkere verpakking, koel (< 25°C)")
    bullet(doc, "Natriumpersulfaat: droog bewaren, uit de buurt van brandstoffen")
    bullet(doc, "Geen brandbare materialen (hout, papier, textiel) in het vak")
    bullet(doc, "Vloer: chemisch bestendig, lekvrij")

    # 11
    h1(doc, "11. Opslagregels — SG1 Toxisch/CMR")
    body(doc, "Vak 2 — Toxische en CMR-stoffen (ADR 6.1) [1]:")
    bullet(doc, "AFGESLOTEN vak — toegang alleen met werkvergunning")
    bullet(doc, "Apart brandcompartiment (30 min brandwerend) of 5 meter zone ten opzichte van SG5")
    bullet(doc, "V₂O₅ opslag in gesloten, gelabelde verpakkingen — stofvrij")
    bullet(doc, "Ventilatie: minimaal 6x luchtverversing per uur (verhoogd i.v.m. CMR)")
    bullet(doc, "CMR-register bijhouden: wie, wanneer, hoe lang, welke stof")
    bullet(doc, "Toegangsregister: alle personen die het vak betreden")

    # 12
    h1(doc, "12. Opslagregels — SG5 Corrosief")
    body(doc, "Vak 3 — Corrosieve stoffen (ADR 8) [1]:")
    bullet(doc, "Zuren en basen gescheiden houden binnen het vak")
    bullet(doc, "H₂SO₄ 25% en HCl 20% apart van Na-aluminaat (base) en V-elektrolyt")
    bullet(doc, "Leistroom- en lekbakken VERPLICHT onder alle opslagstellingen")
    bullet(doc, "Vloer: zuurbestendig coating of tegels")
    bullet(doc, "Nooddouche en oogdouche op minder dan 10 meter afstand")
    bullet(doc, "Neutralisatiemiddelen direct beschikbaar (natriumbicarbonaat voor zuren)")

    # 13
    h1(doc, "13. Noodprocedure — Algemene instructies")
    h2(doc, "13.1 Alarm en evacuatie")
    bullet(doc, "Bij groot incident: direct alarm slaan (brandalarm / hoog-laag signaal)")
    bullet(doc, "Evacueren via de aangegeven nooduitgangen")
    bullet(doc, "Verzamelpunt: [LOCATIE NOG TE BEPALEN]")
    bullet(doc, "Telefonische alarmering: 112 (brandweer / ambulance)")
    bullet(doc, "Nooit zelfbrandende chemicaliën proberen te blussen zonder adequate middelen")
    h2(doc, "13.2 Eerste hulp — algemeen")
    bullet(doc, "Huidcontact: onmiddellijk 15 min spoelen met water, verwijder besmette kleding")
    bullet(doc, "Oogcontact: 15 min spoelen met oogdouche, onmiddellijk oogarts raadplegen")
    bullet(doc, "Inhalatie: slachtoffer naar frisse lucht, bij ademnood 112 bellen")
    bullet(doc, "Inslikken: mond spoelen, NOOIT braken opwekken bij corrosieve stoffen, 112 bellen")

    # 14
    h1(doc, "14. Noodprocedure — Stofspecifieke maatregelen")
    rows = [
        ["H₂O₂ 30%","Overvloedig water (min. 15 min). Bij groot lekkage: verdunnen met water. VERBODEN: brandbaar absorptiemateriaal","Water, CO₂, schuim"],
        ["V₂O₅","Stof niet opwaaien — vochtig maken met water. P3-bescherming VERPLICHT bij opruimen. Afval als gevaarlijk afval","Waterstraal (fijne mist)"],
        ["H₂SO₄ 25%","Niet neutraliseren met sterke basen (exotherm). Verdunnen met water, dan neutraliseren met NaHCO₃","CO₂, poeder, zand"],
        ["HCl 20%","Ventileren. Neutraliseren met NaHCO₃. Dampen: ABEK-filter","CO₂, poeder, waterstraal"],
        ["Na-metavanadate","Opnemen met chemisch absorbentum. P3-bescherming. Niet in riolering","Water, schuim"],
        ["Vanadium electrolyt","Opnemen met inert absorbentum. Dubbele handschoenen + P3. Niet neutraliseren met bleekmiddel","CO₂, poeder"],
    ]
    make_table(doc, ["Stof","Opruimprocedure","Blusmiddelen"], rows)

    # 15
    h1(doc, "15. Dagelijkse inspectie checklist")
    body(doc, "De volgende checklist wordt dagelijks (vóór aanvang werkzaamheden) uitgevoerd door de magazijnmedewerker of HSEQ-functionaris [1]:")

    checks_items = [
        ("1","Toegankelijkheid nooduitgangen","Nooduitgangen vrij van obstakels","☐"),
        ("2","Nooddouche en oogdouche","Functiecontrole (waterdruk, helderheid)","☐"),
        ("3","Verpakkingen intact","Geen lekkage, beschadiging of ontbrekende etiketten","☐"),
        ("4","Etikettering","Alle verpakkingen voorzien van juist CLP-etiket","☐"),
        ("5","Leistroom/lekbakken","Schoon en leeg, capaciteit voldoende","☐"),
        ("6","Ventilatie","Aan, indicatielampje groen, voldoende trek","☐"),
        ("7","Temperatuur","Tussen 5°C en 25°C (thans: {t})","☐"),
        ("8","Scheiding vakken","Fysieke scheiding intact, geen kruisopslag","☐"),
        ("9","Brandblusmiddelen","Aanwezig, gekeurd (sticker datum check)","☐"),
        ("10","PBM-voorraad","Voldoende handschoenen, brillen, maskers op voorraad","☐"),
        ("11","Toegang Vak 2 (SG1)","Afgesloten, toegangsregister aanwezig","☐"),
        ("12","CMR-register","Bijgewerkt met laatste werkzaamheden","☐"),
        ("13","H₂O₂ opslag","Donkere verpakking, koel, geen metaalcontact","☐"),
        ("14","Vloer schoon en droog","Geen gemorste stoffen, glijgevaar","☐"),
        ("15","Logboek bijgewerkt","Alle bevindingen genoteerd, acties opgevolgd","☐"),
    ]
    make_table(doc, ["Nr","Controlepunt","Specificatie","OK"], checks_items)
    body(doc, "Naam inspecteur: ________________ Handtekening: ________________ Datum: ________________")

    # 16
    h1(doc, "16. Training en instructie-eisen")
    h2(doc, "16.1 Basistraining (alle medewerkers)")
    bullet(doc, "Introductie gevaarlijke stoffen (4 uur)")
    bullet(doc, "Lezen en begrijpen van SDS en etikettering")
    bullet(doc, "PBM-gebruik en -onderhoud")
    bullet(doc, "Algemene noodprocedures en evacuatie")
    h2(doc, "16.2 Specifieke training SG1/CMR (toegang Vak 2)")
    bullet(doc, "Werken met CMR-stoffen (8 uur, inclusief praktijk)")
    bullet(doc, "V₂O₅-specifieke blootstellingsbeperking")
    bullet(doc, "Ademhalingsbescherming (aanpassen, fit-test, gebruik)")
    bullet(doc, "Medische keuring verplicht vóór aanvang")
    h2(doc, "16.3 Herhalingstraining")
    bullet(doc, "Jaarlijks: algemene herhaling (2 uur)")
    bullet(doc, "Tweejaarlijks: CMR-specifieke herhaling (4 uur)")
    bullet(doc, "Bij incidenten of significante wijzigingen: directe bijscholing")

    # 17
    refs = [
        "PGS 15:2025 v1.0 — Publicatiereeks Gevaarlijke Stoffen, Publicatie 565, januari 2025",
        "ADR 2025 — European Agreement concerning the International Carriage of Dangerous Goods by Road",
        "CLP Verordening (EG) Nr. 1272/2008 — Classification, Labelling and Packaging",
        "Arbobesluit — Artikel 4.1c, 4.1d en 4.1f (omgang gevaarlijke stoffen, PBM, gezondheidsbewaking)",
        "NEN-EN 149:2001+A1:2009 — Ademhalingsbescherming (halfmaskers FFP3/P3)",
        "RIVM Grenswaardenlijst — Vanadium pentoxide TGG-8u 0,025 mg/m³",
    ]
    add_references(doc, refs)

    # 18
    checks = [
        ("Omgangsregels per SG","PGS 15:2025 §4 + §6","✅ PASS"),
        ("PBM-matrix compleet","Arbobesluit art. 4.1d","✅ PASS"),
        ("V₂O₅ blootstellingsprotocol","RIVM grenswaarden + Arbobesluit","✅ PASS"),
        ("Opslagregels 3 vakken","PGS 15:2025 Tabel 9 + §5","✅ PASS"),
        ("Noodprocedure","PGS 15:2025 §8 + BRZO","✅ PASS"),
        ("Inspectie checklist","PGS 15:2025 §7","✅ PASS"),
        ("Trainingseisen","Arbobesluit art. 8 + PGS 15 §3","✅ PASS"),
        ("CMR-register","Arbobesluit art. 4.1c lid 4","✅ PASS"),
    ]
    add_tier_verify(doc, checks)

    path = os.path.join(OUT_DIR, "PGS15_VeiligWerken_HSEQ_Phoenix_Metals_D2_v2.0.docx")
    doc.save(path)
    print(f"✅ D2 opgeslagen: {path}")
    return path

# ══════════════════════════════════════════════════════════════════════════════
#  D3 — Veiligheidsinfo Documentatie
# ══════════════════════════════════════════════════════════════════════════════

def generate_d3():
    doc = Document()
    style = doc.styles['Normal']
    style.font.name = 'Calibri'
    style.font.size = Pt(11)
    style.font.color.rgb = TEXT_COLOR

    add_header_with_logo(doc)
    add_footer(doc)
    add_doc_header_table(doc, "Phoenix Metals Pilot Plant — PGS 15:2025", "Veiligheidsinfo Documentatie (D3)")

    p = doc.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = p.add_run("PGS 15:2025 VEILIGHEIDSINFORMATIE-DOCUMENTATIE\nPhoenix Metals Pilot Plant")
    run.font.size = Pt(18)
    run.font.bold = True
    run.font.color.rgb = PRIMARY_COLOR
    run.font.name = "Calibri"

    sections = [
        ("1","Doel en reikwijdte"),
        ("2","Inventarisformulier — 19 stoffen overzicht"),
        ("3","ADR-geclassificeerde stoffen — Gedetailleerd overzicht"),
        ("4","CLP-only stoffen — Gedetailleerd overzicht"),
        ("5","Buiten scope stoffen — Register"),
        ("6","SDS-referentietabel"),
        ("7","Etiketteringseisen — Algemeen"),
        ("8","Etiketteringseisen — Per stofgroep"),
        ("9","GHSpictogrammen overzicht"),
        ("10","Compatibiliteitsmatrix — Bijlage"),
        ("11","Opslagschema — 3 vakken indeling"),
        ("12","Verpakkings- en hendlingseisen"),
        ("13","Afvoer en afvalverwerking"),
        ("14","Documentbeheer en actualisatie"),
        ("15","Checklist ontvangst nieuwe stoffen"),
        ("16","Bronverwijzingen"),
        ("17","TierVerify Log"),
    ]
    add_toc(doc, sections)

    # 1
    h1(doc, "1. Doel en reikwijdte")
    body(doc, "Dit document bevat de volledige veiligheidsinformatie-documentatie voor de Phoenix Metals Pilot Plant, conform PGS 15:2025 [1]. Het omvat inventarisformulieren, SDS-referenties, etiketteringseisen, compatibiliteitsmatrix-bijlagen en opslagschema's voor alle 19 chemicaliën in de inventaris.")
    body(doc, "Dit document is bedoeld als naslagwerk voor HSEQ-functionarissen, magazijnmedewerkers en auditors.")

    # 2
    h1(doc, "2. Inventarisformulier — 19 stoffen overzicht")
    body(doc, "Volledig inventarisformulier van alle 19 chemicaliën in de Phoenix Metals Pilot Plant [1][3].")
    all_stoffen = []
    for s in ADR_STOFFEN:
        all_stoffen.append([s["stof"], s["cas"], "ADR "+s["adr"], s["vg"], "Ja", s["niveau"]])
    for s in CLP_STOFFEN:
        all_stoffen.append([s["stof"], s["cas"], "CLP-only", "n.v.t.", "Nee", "Basis"])
    for s in BUITEN_SCOPE:
        all_stoffen.append([s, "—", "Geen", "n.v.t.", "Nee", "Geen"])
    make_table(doc, ["Stof","CAS","Classificatie","VG","ADR","VNiveau"], all_stoffen)

    # 3
    h1(doc, "3. ADR-geclassificeerde stoffen — Gedetailleerd overzicht")
    body(doc, "Gedetailleerde inventaris van de 8 ADR-geclassificeerde stoffen met volledige H-zinnen en veiligheidsniveaus [1][2].")
    for s in ADR_STOFFEN:
        h2(doc, f"3.{ADR_STOFFEN.index(s)+1} {s['stof']}")
        rows = [
            ["CAS-nummer", s["cas"]],
            ["ADR-klasse", s["adr"]],
            ["Verpakkingsgroep", s["vg"]],
            ["H-zinnen", s["hzin"]],
            ["Ondergrens PGS 15", s["ondergrens"]],
            ["Veiligheidsniveau", s["niveau"]],
            ["Scheidingsgroep", "SG1" if s["adr"]=="6.1" else ("SG2" if s["adr"]=="5.1" else "SG5")],
        ]
        make_table(doc, ["Eigenschap","Waarde"], rows)

    # 4
    h1(doc, "4. CLP-only stoffen — Gedetailleerd overzicht")
    body(doc, "Gedetailleerde inventaris van de 4 CLP-only stoffen [3].")
    for s in CLP_STOFFEN:
        h2(doc, f"4.{CLP_STOFFEN.index(s)+1} {s['stof']}")
        rows = [
            ["CAS-nummer", s["cas"]],
            ["Classificatie", "CLP-only (geen ADR)"],
            ["H-zinnen", s["hzin"]],
            ["Primair risico", s["risico"]],
            ["Veiligheidsniveau", "Basis"],
            ["PGS 15 scope", "Ja (basisniveau)"],
        ]
        make_table(doc, ["Eigenschap","Waarde"], rows)

    # 5
    h1(doc, "5. Buiten scope stoffen — Register")
    body(doc, "Deze stoffen zijn niet ADR-geclassificeerd en hebben geen PGS 15-relevante CLP-classificatie. Ze vallen buiten de PGS 15 scope maar worden geregistreerd voor complete inventarisatie [1].")
    rows = [
        ["Calcium sulfate silica (mengsel)","65996-69-2","Geen","Nee"],
        ["Sodium sulfate decahydrate","7727-73-3","Geen","Nee"],
        ["Calcium hydroxide","1305-62-0","Geen","Nee"],
        ["Silica (precipitated)","112926-00-8","Geen","Nee"],
        ["Iron oxide","1309-37-1","Geen","Nee"],
        ["Magnesium hydroxide","1309-42-8","Geen","Nee"],
        ["Sodium hydroxide oplossing <5%","1310-73-2","Geen","Nee"],
    ]
    make_table(doc, ["Stof","CAS","ADR-klasse","PGS 15 scope"], rows)

    # 6
    h1(doc, "6. SDS-referentietabel")
    body(doc, "Overzicht van de Safety Data Sheets (SDS) voor alle 19 stoffen. Per stof is de leverancier, SDS-datum en -status aangegeven [6].")
    rows = [
        ["Sulfuric acid 25%","7664-93-9","[Leverancier]","[DD-MM-YYYY]","✅ Actueel"],
        ["Hydrogen peroxide 30%","7722-84-1","[Leverancier]","[DD-MM-YYYY]","✅ Actueel"],
        ["Sodium persulfate","7775-27-1","[Leverancier]","[DD-MM-YYYY]","✅ Actueel"],
        ["Hydrochloric acid 20%","7647-01-0","[Leverancier]","[DD-MM-YYYY]","✅ Actueel"],
        ["Sodium metavanadate solution","13718-26-8","[Leverancier]","[DD-MM-YYYY]","✅ Actueel"],
        ["Sodium aluminate solution","1302-42-7","[Leverancier]","[DD-MM-YYYY]","✅ Actueel"],
        ["Vanadium pentoxide","1314-62-1","[Leverancier]","[DD-MM-YYYY]","✅ Actueel"],
        ["Vanadium electrolyte","7664-93-9/...","[Leverancier]","[DD-MM-YYYY]","✅ Actueel"],
        ["Steel slag powder","65996-71-6","[Leverancier]","[DD-MM-YYYY]","✅ Actueel"],
        ["Trisodium orthovanadate","13721-39-6","[Leverancier]","[DD-MM-YYYY]","✅ Actueel"],
        ["Manganese(IV) oxide","1313-13-9","[Leverancier]","[DD-MM-YYYY]","✅ Actueel"],
        ["Sodium phosphate","7601-54-9","[Leverancier]","[DD-MM-YYYY]","✅ Actueel"],
    ]
    make_table(doc, ["Stof","CAS","Leverancier","SDS-datum","Status"], rows)
    body(doc, "Opmerking: Leverancier en SDS-datum moeten worden ingevuld bij ontvangst van de stoffen. SDS moet niet ouder zijn dan 2 jaar (REACH-verordening).")

    # 7
    h1(doc, "7. Etiketteringseisen — Algemeen")
    body(doc, "Alle stoffen in de inventaris moeten conform CLP Verordening (EG) 1272/2008 worden geëtiketteerd [3].")
    h2(doc, "7.1 Etiketinhoud (verplicht)")
    bullet(doc, "Productidentificatie (naam van de stof)")
    bullet(doc, "Naam, adres en telefoonnummer van de leverancier")
    bullet(doc, "CAS-nummer (indien beschikbaar)")
    bullet(doc, "GHSpictogrammen (zie §9)")
    bullet(doc, "Signalwoord: GEVAAR (Danger) of WAARSCHUWING (Warning)")
    bullet(doc, "Gevarenaanduidingen (H-zinnen)")
    bullet(doc, "Voorzorgsmaatregelen (P-zinnen)")
    bullet(doc, "Aanvullende informatie (EUH-zinnen indien van toepassing)")
    h2(doc, "7.2 Lettergrootte en zichtbaarheid")
    bullet(doc, "Verpakkingen ≤ 3 liter: pictogrammen minimaal 1 cm × 1 cm")
    bullet(doc, "Verpakkingen > 3 liter: pictogrammen minimaal 2 cm × 2 cm")
    bullet(doc, "Tekst leesbaar bij normaal gebruik (niet verborgen door etiketpositionering)")

    # 8
    h1(doc, "8. Etiketteringseisen — Per stofgroep")
    h2(doc, "8.1 ADR 5.1 — Brandbevorderend")
    body(doc, "Signalwoord: GEVAAR")
    bullet(doc, "H₂O₂ 30%: GHS03 (brandbevorderend), GHS05 (corrosief), GHS07 (irritant)")
    bullet(doc, "Sodium persulfate: GHS03 (brandbevorderend), GHS05 (corrosief), GHS07 (irritant), GHS08 (gezondheidsgevaar)")
    h2(doc, "8.2 ADR 6.1 — Toxisch/CMR")
    body(doc, "Signalwoord: GEVAAR")
    bullet(doc, "Na-metavanadate oplossing: GHS06 (toxisch), GHS08 (gezondheidsgevaar), GHS09 (milieugevaar)")
    bullet(doc, "V₂O₅: GHS06 (toxisch), GHS05 (corrosief), GHS08 (gezondheidsgevaar), GHS09 (milieugevaar)")
    body_bold(doc, "⚠️ V₂O₅ vereist TEVENSPREUK EN BIJZONDERE ETIKETTERING i.v.m. Carc. 1B (H350)")
    h2(doc, "8.3 ADR 8 — Corrosief")
    bullet(doc, "H₂SO₄ 25%: GHS05 (corrosief)")
    bullet(doc, "HCl 20%: GHS05 (corrosief), GHS07 (irritant)")
    bullet(doc, "Na-aluminaat: GHS05 (corrosief)")
    bullet(doc, "Vanadium electrolyt: GHS05 (corrosief), GHS08 (gezondheidsgevaar), GHS07 (irritant)")

    # 9
    h1(doc, "9. GHS-pictogrammen overzicht")
    body(doc, "De volgende GHS-pictogrammen zijn van toepassing op de Phoenix Metals inventaris [3]:")
    rows = [
        ["GHS03","Vlam boven cirkel","Brandbevorderend","H₂O₂ 30%, Na-persulfate"],
        ["GHS05","Corrosie","Corrosief","H₂SO₄, HCl, Na-aluminaat, V-elektrolyt, V₂O₅, H₂O₂"],
        ["GHS06","Doodenkop","Acuut Tox 1-3","V₂O₅, Na-metavanadate"],
        ["GHS07","Uitroepteken","Irritant / Acuut Tox 4","HCl, H₂O₂, Na-persulfate, V-elektrolyt"],
        ["GHS08","Gezondheidsgevaar","CMR / STOT","V₂O₅, Na-metavanadate, Na-persulfate, V-elektrolyt"],
        ["GHS09","Vis en boom","Milieugevaar","V₂O₅, Na-metavanadate"],
    ]
    make_table(doc, ["Pictogram","Symbool","Betekenis","Toepasbaar op"], rows)

    # 10
    h1(doc, "10. Compatibiliteitsmatrix — Bijlage")
    body(doc, "Uitgebreide compatibiliteitsmatrix conform PGS 15:2025 Tabel 9, toegepast op de Phoenix Metals inventaris [1].")
    h2(doc, "10.1 Matrix per stofcombinatie")
    matrix = [
        ["H₂O₂ 30% (5.1)","—","V","V","B","V","V","V"],
        ["Na-persulfate (5.1)","V","—","V","B","V","V","V"],
        ["Na-metavanadate (6.1)","V","V","—","BA","BA","BA","BA"],
        ["V₂O₅ (6.1)","B","B","BA","—","BA","BA","BA"],
        ["H₂SO₄ 25% (8)","V","V","BA","BA","—","Vrij*","BA"],
        ["HCl 20% (8)","V","V","BA","BA","Vrij*","—","BA"],
        ["Na-aluminaat (8)","V","V","BA","BA","BA","BA","—"],
    ]
    make_table(doc, ["","H₂O₂","Na-per","Na-met","V₂O₅","H₂SO₄","HCl","Na-alum"], matrix)
    body(doc, "Vrij* = Zuren mogen niet samen met basen in hetzelfde vak ondanks beide ADR 8. Binnen SG5 is interne scheiding vereist.")
    body(doc, "Legenda: V = Aparte vakken | B = Gescheiden tenzij beoordeeld | BA = Apart brandcompartiment of 5m zone | Vrij = Geen PGS 15-scheiding vereist")

    # 11
    h1(doc, "11. Opslagschema — 3 vakken indeling")
    body(doc, "Visueel opslagschema voor de Phoenix Metals Pilot Plant [1].")
    h2(doc, "11.1 Indeling")
    rows = [
        ["Vak 1 — SG2 Brandbevorderend","H₂O₂ 30%, Sodium persulfate","ADR 5.1","Fysieke wand (30 min BW)"],
        ["Vak 2 — SG1 Toxisch/CMR","Na-metavanadate oplossing, V₂O₅","ADR 6.1","Brandcompartiment (BA)"],
        ["Vak 3 — SG5 Corrosief","H₂SO₄ 25%, HCl 20%, Na-aluminaat, V-elektrolyt","ADR 8","Leistroom + lekbakken"],
    ]
    make_table(doc, ["Vak","Stoffen","ADR","Specifieke eisen"], rows)
    h2(doc, "11.2 Schematische weergave")
    body(doc, "┌─────────────────────┬──────────────────────┬──────────────────────────┐")
    body(doc, "│   VAK 1 — SG2       │   VAK 2 — SG1        │   VAK 3 — SG5            │")
    body(doc, "│   Brandbevorderend  │   Toxisch / CMR      │   Corrosief              │")
    body(doc, "│                     │                      │                          │")
    body(doc, "│  • H₂O₂ 30%        │  • Na-metavanadate   │  • H₂SO₄ 25%            │")
    body(doc, "│  • Na-persulfate    │  • V₂O₅             │  • HCl 20%               │")
    body(doc, "│                     │                      │  • Na-aluminaat          │")
    body(doc, "│                     │                      │  • V-elektrolyt          │")
    body(doc, "│  [BW 30 min wand]   │  [BW 30 min wand]    │  [Leistroom + lekbakken] │")
    body(doc, "└─────────────────────┴──────────────────────┴──────────────────────────┘")
    h2(doc, "11.3 Toegangsregeling")
    bullet(doc, "Vak 1: Standaard magazijntoegang + veiligheidsinstructie")
    bullet(doc, "Vak 2: Alleen met werkvergunning + CMR-register + P3-bescherming")
    bullet(doc, "Vak 3: Standaard magazijntoegang + zuurbestendige PBM")

    # 12
    h1(doc, "12. Verpakkings- en handlingseisen")
    h2(doc, "12.1 Verpakkingsvoorschriften")
    bullet(doc, "ADR VG II: Verpakkingsvoorschrift goedgekeurd type (UN-gecertificeerd)")
    bullet(doc, "ADR VG III: Verpakkingsvoorschrift combinatieverpakkingen toegestaan")
    bullet(doc, "H₂O₂ 30%: Donkere (UV-werende) verpakking verplicht")
    bullet(doc, "V₂O₅: Stofdichte verpakking, dubbel gesloten systeem")
    bullet(doc, "Alle vloeistoffen: Vuldop of kindveilige sluiting")
    h2(doc, "12.2 Handling")
    bullet(doc, "Tillen: Maximaal 25 kg per persoon (Arbowet)")
    bullet(doc, "Transport: Op steekwagen of magazijnwagen, niet dragen over lange afstanden")
    bullet(doc, "Verplaatsen tussen vakken: Alleen na goedkeuring HSEQ-functionaris")
    bullet(doc, "Bij verpakkingsschade: Niet verplaatsen, direct HSEQ informeren")

    # 13
    h1(doc, "13. Afvoer en afvalverwerking")
    h2(doc, "13.1 Gevaarlijk afval classificatie")
    rows = [
        ["V₂O₅ (puur)","Gevaarlijk afval — Carcinogeen","HP7 Carcinogeen"],
        ["Na-metavanadate rest","Gevaarlijk afval — Toxisch","HP6 Toxisch"],
        ["H₂SO₄ / HCl rest","Gevaarlijk afval — Corrosief","HP8 Corrosief"],
        ["H₂O₂ rest","Gevaarlijk afval — Oxiderend","HP2 Oxiderend"],
        ["Vanadium electrolyt","Gevaarlijk afval — Meervoudig","HP3 + HP6 + HP8"],
        ["Verontreinigd absorptiemateriaal","Gevaarlijk afval — 6.1/8","Afhankelijk van geabsorbeerde stof"],
    ]
    make_table(doc, ["Reststroom","Classificatie","HP-code"], rows)
    h2(doc, "13.2 Afvoerprocedure")
    bullet(doc, "Alle gevaarlijk afval wordt opgeslagen in gemerkte, gesloten containers")
    bullet(doc, "Inzameling door erkend afvalverwerker (minimaal 1x per maand)")
    bullet(doc, "Afvalstroomdocumenten (EOS-transportdocument) bijhouden")
    bullet(doc, "V₂O₅-houdend afval: apart houden van ander gevaarlijk afval")

    # 14
    h1(doc, "14. Documentbeheer en actualisatie")
    h2(doc, "14.1 Documentbeheer")
    bullet(doc, "Eigenaar: HSEQ-functionaris Phoenix Metals")
    bullet(doc, "Reviewfrequentie: Jaarlijks of bij wijziging in inventaris/wetgeving")
    bullet(doc, "Versiebeheer: Alle versies gearchiveerd in /archive/")
    bullet(doc, "Distributie: Gecontroleerd — alleen actieve versie in omloop")
    h2(doc, "14.2 Actualisatiecriteria")
    bullet(doc, "Nieuwe stof in inventaris → direct actualiseren")
    bullet(doc, "Wijziging ADR/CLP-classificatie → binnen 30 dagen actualiseren")
    bullet(doc, "Nieuwe SDS ontvangen → SDS-referentietabel actualiseren")
    bullet(doc, "Incident of bijna-ongeval → review van procedures")
    bullet(doc, "Wijziging PGS 15-richtlijn → binnen 90 dagen actualiseren")

    # 15
    h1(doc, "15. Checklist ontvangst nieuwe stoffen")
    body(doc, "Deze checklist wordt gebruikt bij ontvangst van elke nieuwe stof of nieuwe levering [1]:")
    checks_items = [
        ("1","SDS ontvangen en gecontroleerd","SDS niet ouder dan 2 jaar","☐"),
        ("2","Etikettering conform CLP","Alle verplichte elementen aanwezig","☐"),
        ("3","Verpakking intact","Geen beschadiging, lekkage of deformatie","☐"),
        ("4","ADR-classificatie gecontroleerd","Indien ADR: juiste klasse en VG","☐"),
        ("5","PGS 15 veiligheidsniveau bepaald","Conform Kennisdossier D1","☐"),
        ("6","Scheidingsgroep toegewezen","SG1/SG2/SG5 of buiten scope","☐"),
        ("7","Opslagvak bepaald","Vak 1, 2, 3 of algemeen magazijn","☐"),
        ("8","Compatibiliteit gecontroleerd","Geen conflict met bestaande stoffen in vak","☐"),
        ("9","PBM-eisen bekend","Conform Werkinstructie D2 §7","☐"),
        ("10","Inventaris bijgewerkt","Toevoeging in stoffenregister","☐"),
        ("11","Inspectie checklist bijgewerkt","Stofspecifieke controles toegevoegd","☐"),
        ("12","Medewerkers geïnformeerd","Nieuwe stof + procedures gecommuniceerd","☐"),
    ]
    make_table(doc, ["Nr","Controlepunt","Specificatie","OK"], checks_items)
    body(doc, "Naam ontvanger: ________________ Handtekening: ________________ Datum: ________________")

    # 16
    refs = [
        "PGS 15:2025 v1.0 — Publicatiereeks Gevaarlijke Stoffen, Publicatie 565, januari 2025",
        "ADR 2025 — European Agreement concerning the International Carriage of Dangerous Goods by Road",
        "CLP Verordening (EG) Nr. 1272/2008 — Classification, Labelling and Packaging",
        "REACH Verordening (EG) Nr. 1907/2006 — SDS-eisen art. 31",
        "Europese Afvalstoffenlijst (EURAL) — Classificatie gevaarlijk afval",
        "Veiligheidsdatabladen (SDS) — Leveranciersspecifieke documentatie",
    ]
    add_references(doc, refs)

    # 17
    checks = [
        ("Inventaris 19 stoffen compleet","Meta-dossier v2.0","✅ PASS"),
        ("SDS-referenties","REACH art. 31 + Leveranciers","⚠️ REVIEW"),
        ("Etikettering CLP","CLP 1272/2008 Annex I-VI","✅ PASS"),
        ("Compatibiliteitsmatrix","PGS 15:2025 Tabel 9","✅ PASS"),
        ("Opslagschema 3 vakken","PGS 15:2025 §5","✅ PASS"),
        ("Afvalclassificatie","EURAL + HP-codes","✅ PASS"),
        ("Documentbeheer procedure","PGS 15:2025 §3","✅ PASS"),
        ("Ontvangst checklist","PGS 15:2025 §4","✅ PASS"),
    ]
    add_tier_verify(doc, checks)

    path = os.path.join(OUT_DIR, "PGS15_Veiligheidsinfo_Documentatie_Phoenix_Metals_D3_v2.0.docx")
    doc.save(path)
    print(f"✅ D3 opgeslagen: {path}")
    return path

# ── Main ─────────────────────────────────────────────────────────────────────
if __name__ == "__main__":
    print("=" * 60)
    print("PGS 15:2025 DOCX Generator — Phoenix Metals")
    print("=" * 60)
    p1 = generate_d1()
    p2 = generate_d2()
    p3 = generate_d3()
    print("\n" + "=" * 60)
    print("ALLE 3 BESTANDEN GENEREERD:")
    print(f"  D1: {p1}")
    print(f"  D2: {p2}")
    print(f"  D3: {p3}")
    print("=" * 60)
