#!/usr/bin/env python3
"""
Generate D1 v3.0 (REACH Kennisdossier) and D2 v3.0 (VeiligWerken HSEQ Framework)
for Phoenix Metals — DOCX output with JvG Consultancy branding.
"""

import os
from docx import Document
from docx.shared import Inches, Pt, Cm, RGBColor
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

LOGO_PATH = "/root/projects/jg/assets/branding/jvg-logo-white-medium.png"
OUTPUT_DIR = "/root/projects/jg/2026-reach-phoenix-metals/deliverables/docx"

# ──────────────────────────────────────────────────────────────────────
# HELPER FUNCTIONS
# ──────────────────────────────────────────────────────────────────────

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

def add_styled_table(doc, headers, rows, col_widths=None):
    """Add a formatted table with JvG header row."""
    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.bold = True
        run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
        run.font.size = Pt(9)
        p.alignment = WD_ALIGN_PARAGRAPH.LEFT
        set_cell_shading(cell, "003366")

    # Data rows
    for r_idx, row_data in enumerate(rows):
        for c_idx, val in enumerate(row_data):
            cell = table.rows[r_idx + 1].cells[c_idx]
            cell.text = str(val)
            for p in cell.paragraphs:
                for run in p.runs:
                    run.font.size = Pt(9)
            if r_idx % 2 == 1:
                set_cell_shading(cell, "E8EDF2")

    return table

def add_section(doc, number, title):
    """Add a numbered section heading."""
    p = doc.add_heading(f"{number} {title}", level=1)
    for run in p.runs:
        run.font.color.rgb = RGBColor(0x00, 0x33, 0x66)

def add_subsection(doc, number, title):
    """Add a numbered sub-section heading."""
    p = doc.add_heading(f"{number} {title}", level=2)
    for run in p.runs:
        run.font.color.rgb = RGBColor(0x00, 0x33, 0x66)

def add_body(doc, text):
    """Add body paragraph with source reference support."""
    p = doc.add_paragraph(text)
    p.paragraph_format.space_after = Pt(6)
    for run in p.runs:
        run.font.size = Pt(10)
    return p

def add_bullet(doc, text, level=0):
    p = doc.add_paragraph(text, style='List Bullet')
    p.paragraph_format.left_indent = Cm(1.27 + level * 1.27)
    for run in p.runs:
        run.font.size = Pt(10)
    return p

def setup_document(title, subtitle):
    """Create document with header/footer branding."""
    doc = Document()
    
    # Default font
    style = doc.styles['Normal']
    font = style.font
    font.name = 'Calibri'
    font.size = Pt(10)
    
    # Page margins
    for section in doc.sections:
        section.top_margin = Cm(2.5)
        section.bottom_margin = Cm(2.0)
        section.left_margin = Cm(2.5)
        section.right_margin = Cm(2.5)

    # Header with logo
    for section in doc.sections:
        header = section.header
        header.is_linked_to_previous = False
        hp = header.paragraphs[0]
        hp.alignment = WD_ALIGN_PARAGRAPH.LEFT
        
        # Set header background color
        pPr = hp._p.get_or_add_pPr()
        shd = parse_xml(f'<w:shd {nsdecls("w")} w:fill="003366" w:val="clear"/>')
        pPr.append(shd)
        
        if os.path.exists(LOGO_PATH):
            run = hp.add_run()
            run.add_picture(LOGO_PATH, height=Cm(1.0))
        
        run2 = hp.add_run(f"    JvG Consultancy — {subtitle}")
        run2.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
        run2.font.size = Pt(9)
        run2.bold = True

        # Footer with page number
        footer = section.footer
        footer.is_linked_to_previous = False
        fp = footer.paragraphs[0]
        fp.alignment = WD_ALIGN_PARAGRAPH.CENTER
        
        run_f = fp.add_run("JvG Consultancy  |  REACH Compliance Advisory  |  Pagina ")
        run_f.font.size = Pt(8)
        run_f.font.color.rgb = RGBColor(0x00, 0x33, 0x66)
        
        # Page number field
        fldChar1 = parse_xml(f'<w:fldChar {nsdecls("w")} w:fldCharType="begin"/>')
        run_pn1 = fp.add_run()
        run_pn1._r.append(fldChar1)
        
        instrText = parse_xml(f'<w:instrText {nsdecls("w")} xml:space="preserve"> PAGE </w:instrText>')
        run_pn2 = fp.add_run()
        run_pn2._r.append(instrText)
        
        fldChar2 = parse_xml(f'<w:fldChar {nsdecls("w")} w:fldCharType="end"/>')
        run_pn3 = fp.add_run()
        run_pn3._r.append(fldChar2)

    # Title page
    for _ in range(6):
        doc.add_paragraph()
    
    tp = doc.add_paragraph()
    tp.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run_t = tp.add_run(title)
    run_t.font.size = Pt(24)
    run_t.font.color.rgb = RGBColor(0x00, 0x33, 0x66)
    run_t.bold = True
    
    tp2 = doc.add_paragraph()
    tp2.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run_t2 = tp2.add_run(subtitle)
    run_t2.font.size = Pt(14)
    run_t2.font.color.rgb = RGBColor(0x00, 0x66, 0x99)
    
    tp3 = doc.add_paragraph()
    tp3.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run_t3 = tp3.add_run("Versie 3.0 — April 2026")
    run_t3.font.size = Pt(12)
    run_t3.font.color.rgb = RGBColor(0x66, 0x66, 0x66)
    
    tp4 = doc.add_paragraph()
    tp4.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run_t4 = tp4.add_run("Opdrachtgever: Phoenix Metals B.V.")
    run_t4.font.size = Pt(11)
    
    tp5 = doc.add_paragraph()
    tp5.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run_t5 = tp5.add_run("Adviseur: JvG Consultancy")
    run_t5.font.size = Pt(11)
    
    tp6 = doc.add_paragraph()
    tp6.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run_t6 = tp6.add_run("CONFIDENTIEEL")
    run_t6.font.size = Pt(11)
    run_t6.font.color.rgb = RGBColor(0xCC, 0x00, 0x00)
    run_t6.bold = True

    doc.add_page_break()
    return doc


# ══════════════════════════════════════════════════════════════════════
# D1: REACH KENNISDOSSIER PHOENIX METALS
# ══════════════════════════════════════════════════════════════════════

def generate_D1():
    doc = setup_document(
        "REACH Kennisdossier\nPhoenix Metals",
        "Regulatorische Analyse & Compliance Roadmap"
    )

    # ── 1. Executive Summary ──
    add_section(doc, "1", "Executive Summary")
    add_body(doc,
        "Phoenix Metals B.V. ('PM') ontwikkelt een innovatief hydrometallurgisch proces voor de "
        "extractie van vanadium, ijzer, calcium en magnesium uit staalslakken afkomstig van Tata Steel "
        "Netherlands. De pilot plant is voorzien op de locatie Westerduinweg 3 in de haven van IJmuiden "
        "(gemeente Velsen). De jaarlijkse verwerkingscapaciteit in de pilotfase bedraagt 80–120 ton "
        "staalslakken, met een opschalingsdoel naar 6.000.000 liter vanadiumelektrolyt op commerciële "
        "schaal. (Haalbaarheidsstudie Phoenix Metals IJmuiden, Arcadis, §1; Uitgangspuntendocument, §1)"
    )
    add_body(doc,
        "Dit kennisdossier analyseert de REACH-verordening (EG nr. 1907/2006) en gerelateerde "
        "regelgeving in de context van de Phoenix Metals bedrijfsvoering. De kernvraag is of en hoe PM "
        "moet registreren onder REACH, met specifieke aandacht voor: (i) de End-of-Waste status van "
        "staalslakken als ingaande grondstof, (ii) de Art. 2(7)(d) vrijstelling voor gerecycleerde stoffen, "
        "(iii) stofidentificatie van variabele slaksamenstellingen (UVCB), en (iv) de registratie- en "
        "communicatieverplichtingen langs de volledige supply chain."
    )
    add_body(doc,
        "Conclusie: Phoenix Metals heeft een concrete REACH-compliance verplichting. Het bedrijf "
        "produceert nieuwe stoffen (vanadiumelektrolyt, gips) die boven de 1 ton/jaar drempel vallen en "
        "moet daarom een registratiedossier voorbereiden. De End-of-Waste analyse is kritiek: zolang "
        "staalslakken als 'afval' kwalificeren, geldt een REACH-vrijstelling voor de ingaande stroom, maar "
        "zodra de EoW-status wordt bereikt, vervalt deze vrijstelling. Een proactieve aanpak met een "
        "Strategisch Actieplan (§13) is essentieel."
    )

    # ── 2. Bedrijfscontext ──
    add_section(doc, "2", "Bedrijfscontext Phoenix Metals")

    add_subsection(doc, "2.1", "Organisatie en Visie")
    add_body(doc,
        "Phoenix Metals is een startup-scaleup die zich richt op de circulaire extractie van waardevolle "
        "metalen uit industriële reststromen. Het bedrijf is geleid door Managing Director Stijn van Zelst "
        "en is voornemens een HSE Manager aan te stellen voor de opbouw van een robuust "
        "HSE-managementsysteem. (Phoenix Metals HSE Policy-V1, §1–§2; Motivatiebrief HSE Manager, §1)"
    )
    add_body(doc,
        "PM hanteert een HSE-beleid gebaseerd op compliance, risicobeheersing en continue verbetering, "
        "met jaarlijkse targets en management reviews. Het beleid is ondertekend op 1 januari 2025. "
        "(Phoenix Metals HSE Policy-V1, §1–§7)"
    )

    add_subsection(doc, "2.2", "Locatie: PlantOne Rotterdam / IJmuiden")
    add_body(doc,
        "De R&D- en demofase vindt plaats bij Plant One Rotterdam (POR), een bedrijfsverzamelgebouw "
        "voor procesindustrie. De pilot plant is voorzien op de Westerduinweg 3 in de haven van IJmuiden, "
        "gemeente Velsen, direct naast Cebo. De locatie valt onder het bestemmingsplan 'Havengebied "
        "IJmuiden' met bestemming 'Bedrijf – Havengebonden'. (Haalbaarheidsstudie Arcadis V04, §2.1; "
        "Verslag vooroverleg, §Locatie)"
    )

    add_subsection(doc, "2.3", "Procesbeschrijving")
    add_body(doc,
        "Het PM-proces is een hydrometallurgisch extractieproces dat uitsluitend gebruik maakt van "
        "waterige oplossingen zonder ammonia. Het proces is succesvol getest op R&D-schaal (4L batch) "
        "en pre-pilot schaal (20L batch). In de pilotfase wordt opgeschaald naar 3.000L batches. "
        "(Haalbaarheidsstudie Arcadis, §1; Demo Process VR, stappen 1–26)"
    )
    add_body(doc, "Het proces omvat de volgende hoofdactiviteiten:")
    
    process_steps = [
        ("1. Dissolutie", "Staalslak/ash wordt gemengd met water en 50% NaOH, verwarmd tot 80°C onder roeren"),
        ("2. Filtratie", "Scheiding van filterkoek (residu) en filtraat via filterunit"),
        ("3. Kristallisatie", "Koeling van filtraat om kristallisatie te provokeren; herhaalde filtratie"),
        ("4. Zuurbehg", "Toevoeging van 50% H₂SO₄ en aluminiumsulfaat; verwarming tot 80°C"),
        ("5. Ionenuitwisseling", "Filtratie gevolgd door ion-exchange kolom met 2,5M H₂SO₄ regeneratie"),
        ("6. Elektroreductie", "Vanadium(V) wordt gereduceerd tot vanadium(IV) sulfaat oplossing in elektrolysecellen"),
    ]
    add_styled_table(doc, ["Stap", "Omschrijving"], process_steps)
    doc.add_paragraph()

    add_subsection(doc, "2.4", "Chemische Stoffen — Overzicht")
    add_body(doc,
        "De volgende chemische stoffen worden gebruikt in het PM-proces, gebaseerd op de Registration "
        "Chemicals MASTER (v2.1.0) en de uitgangspuntendocumenten. (Chemicals Master, §1; "
        "Uitgangspuntendocument, §1)"
    )
    chemicals = [
        ("NaOH 50%", "1310-73-2", "ADR 8, PG II", "100 L", "Corrosief, H314"),
        ("H₂SO₄ 75%", "7664-93-9", "ADR 8, PG II", "30 L", "Corrosief, H314/H290"),
        ("H₂SO₄ 50%", "7664-93-9", "ADR 8, PG II", "70 L", "Corrosief, H314/H290"),
        ("H₂SO₄ 25%", "7664-93-9", "ADR 8, PG II", "100 L", "Corrosief, H314/H290"),
        ("Al₂(SO₄)₃·18H₂O", "7784-31-8", "N/A", "5 kg", "Niet-geclassificeerd"),
        ("CaO", "1305-78-8", "N/A", "10 kg", "H315/H318"),
        ("V₂O₅ (ingaand)", "1314-62-1", "ADR 6.1, PG III*", "zie massabalans", "Toxisch, H331/H341"),
        ("Vanadiumelektrolyt", "UVCB", "ADR 8, PG III", "uitgaand product", "Corrosief, H314"),
    ]
    add_styled_table(doc, ["Stof", "CAS-nr", "ADR-klasse", "Voorraad pilot", "CLP-classificatie"], chemicals)
    doc.add_paragraph()

    add_subsection(doc, "2.5", "Massabalans")
    add_body(doc,
        "Pilotfase: 80–120 ton staalslakken per jaar → 7.200 kg verwerkt in pilot batches. "
        "Commerciële schaal (6 ML): 1.200 ton V₂O₅ + 7.200 ton H₂SO₄ per jaar → 6.000.000 liter "
        "vanadiumelektrolyt. Nevenproducten: gips (CaSO₄), restchemicaliën (~350.000 L), vast afval "
        "(~50 ton). (Uitgangspuntendocument, §1–§2; Haalbaarheidsstudie Arcadis V04, §1)"
    )

    # ── 3. End-of-Waste Analyse ──
    add_section(doc, "3", "End-of-Waste Analyse")

    add_subsection(doc, "3.1", "Kader: Kaderrichtlijn Afval (KRA)")
    add_body(doc,
        "De KRA (Richtlijn 2008/98/EG) definieert in artikel 6 de voorwaarden waaronder een "
        "bepaalde afvalstof ophoudt afval te zijn (End-of-Waste, EoW). Een stof is geen afval meer "
        "wanneer deze cumulatief voldoet aan: (a) de stof is bestemd om voor bepaalde doeleinden "
        "te worden gebruikt, (b) er is een markt voor of een vraag naar de stof, (c) de stof voldoet "
        "aan de technische vereisten voor de betreffende doeleinden en aan de toepasselijke normen "
        "voor producten, en (d) het gebruik van de stof leidt niet tot nadelige effecten voor mens en "
        "milieu. (KRA art. 6; Duurzaamheid Praktische Gids 13, §2)"
    )

    add_subsection(doc, "3.2", "Toepassing op Phoenix Metals")
    add_body(doc,
        "De ingaande grondstof (staalslakken van Tata Steel) kwalificeert momenteel als afvalstof "
        "in de zin van de KRA. Dit betekent dat REACH-artikel 2(7)(b) van toepassing kan zijn: stoffen "
        "die bij een afvalbehandelingsproces worden verkregen, zijn vrijgesteld van registratie totdat "
        "zij zijn opgenomen in een EoW-beslissing van de Commissie. Echter, zodra PM's uitgaande "
        "producten (vanadiumelektrolyt, gips) de EoW-status bereiken, vallen deze wél onder REACH. "
        "(REACH art. 2(7)(b); Duurzaamheid Praktische Gids 13, §3.1)"
    )

    add_subsection(doc, "3.3", "EoW-Verordening Status")
    add_body(doc,
        "Er is nog geen specifieke EU-EoW-beslissing voor staalslakken of vanadiumconcentraten uit "
        "slakextractie. Dit betekent dat PM de bewijslast draagt om per product aan te tonen dat de "
        "vier EoW-criteria zijn vervuld. Het is aanbevolen om een EoW-dossier voor te bereiden als "
        "onderdeel van het registratietraject. (KRA art. 6, lid 4; Duurzaamheid Praktische Gids 13, §4)"
    )

    # ── 4. Art. 2(7)(d) Analyse ──
    add_section(doc, "4", "Art. 2(7)(d) Analyse — Gerecycleerde Stoffen")
    add_body(doc,
        "REACH artikel 2, lid 7, onderdeel (d) biedt een vrijstelling van registratie, evaluatie en "
        "autorisatie voor stoffen die: (i) in de Gemeenschap zijn vervaardigd of ingevoerd, (ii) al "
        "eerder zijn geregistreerd (door dezelfde of een andere rechtspersoon), en (iii) dezelfde "
        "chemische identiteit hebben als de reeds geregistreerde stof. De vrijstelling geldt alleen als "
        "aan alle drie de voorwaarden cumulatief wordt voldaan. (REACH art. 2(7)(d); ECHA "
        "Registratiegids v4.0, §1.5)"
    )
    add_body(doc, "Voor Phoenix Metals betekent dit:")
    add_bullet(doc, "V₂O₅ (vanadiumpentoxide): Als dit identiek is aan een reeds geregistreerde stof EN PM deze hergebruikt uit een afvalstroom, kan de vrijstelling gelden. Echter, PM gebruikt V₂O₅ als ingaande grondstof (niet als gerecycleerd product), waardoor Art. 2(7)(d) waarschijnlijk niet van toepassing is. (Uitgangspuntendocument, §1)")
    add_bullet(doc, "Vanadiumelektrolyt (uitgaand product): Dit is een nieuwe stof (UVCB) die nog niet is geregistreerd. Art. 2(7)(d) is niet van toepassing. PM moet registreren zodra de productie >1 ton/jaar bedraagt. (REACH art. 2(7)(d); Stofidentificatiegids v3.0, §2.1)")
    add_bullet(doc, "Gips (nevenproduct): Indien het geproduceerde gips identiek is aan reeds geregistreerd calciumsulfaat en wordt gebruikt als product (niet als afval), kan Art. 2(7)(d) van toepassing zijn. Dit vereist een gelijkheidstoets via ECHA-databases. (ECHA Registratiegids v4.0, §1.5.2)")

    # ── 5. Stofidentificatie & SIP ──
    add_section(doc, "5", "Stofidentificatie & Stofidentiteitsprofiel (SIP)")

    add_subsection(doc, "5.1", "REACH-vereisten voor stofidentificatie")
    add_body(doc,
        "Ondubbelzinnige identificatie is een voorwaarde voor een geldig registratiedossier. REACH "
        "onderscheidt: (a) mono-constituent stoffen (hoofdbestanddeel ≥80%), (b) multi-constituent "
        "stoffen (meerdere bestanddelen 10–80%), en (c) UVCB-stoffen (Unknown or Variable "
        "composition, Complex reaction products or Biological materials). (REACH Bijlage VI, §2; "
        "Stofidentificatiegids v3.0, §3.1)"
    )

    add_subsection(doc, "5.2", "UVCB-problematiek bij Phoenix Metals")
    add_body(doc,
        "De vanadiumelektrolyt die PM produceert is een UVCB-stof: de exacte samenstelling varieert "
        "afhankelijk van de slaksamenstelling (die afhankelijk is van het Tata Steel productieproces), "
        "de extractie-effectiviteit en de elektroreductieparameters. Voor UVCB-stoffen moet een "
        "Stofidentiteitsprofiel (SIP) worden opgesteld dat de grenssamenstellingen beschrijft. "
        "(Stofidentificatiegids v3.0, §4.2; SIP Praktische Gids, §3.1–3.2)"
    )
    add_body(doc, "Het SIP voor PM's vanadiumelektrolyt dient minimaal te bevatten:")
    add_bullet(doc, "Chemische naam: 'Reactiemassa van vanadium(IV)sulfaat, zwavelzuur en water'")
    add_bullet(doc, "CAS-nummer: Niet-toegewezen (UVCB) → aanvraag bij CAS vereist")
    add_bullet(doc, "EC-nummer: Niet-toegewezen → aanvraag bij ECHA vereist")
    add_bullet(doc, "Samenstellingsbereik: V(IV) 1,5–2,5 molair, H₂SO₄ 1,0–3,0 molair, H₂O rest")
    add_bullet(doc, "Fysicochemische parameters: dichtheid, viscositeit, kleur, pH")
    add_bullet(doc, "Bronidentificatie: staalslakken van Tata Steel IJmuiden")
    add_body(doc,
        "(SIP Praktische Gids, §3.2; Stofidentificatiegids v3.0, §4.3)"
    )

    add_subsection(doc, "5.3", "QSAR en Read-Across")
    add_body(doc,
        "Voor ontbrekende toxicologische data kan PM gebruikmaken van (Q)SAR-voorspellingen en "
        "read-across, mits de modellen voldoen aan de validatiecriteria van Bijlage XI van REACH. "
        "Dit is met name relevant voor de vanadiumverbindingen waarvoor beperkte chronische "
        "toxiciteitsdata beschikbaar zijn. (QSAR Wegwijzer v3.1, §2.4–2.5)"
    )

    # ── 6. Registratieverplichtingen ──
    add_section(doc, "6", "Registratieverplichtingen")

    add_subsection(doc, "6.1", "1-ton grens en toepassingsgebied")
    add_body(doc,
        "REACH artikel 6 verplicht elke fabrikant of importeur die een stof in hoeveelheden van "
        "1 ton of meer per jaar produceert of importeert, deze stof te registreren bij ECHA. Voor PM "
        "betekent dit dat registratie verplicht is zodra de jaarlijkse productie van vanadiumelektrolyt "
        "(of een andere stof) de 1-ton drempel overschrijdt. Gezien de geplande productiecapaciteit "
        "(6 ML/jaar op commerciële schaal) is registratie onvermijdelijk. (REACH art. 6; ECHA "
        "Registratiegids v4.0, §1.2)"
    )

    add_subsection(doc, "6.2", "Tonnage-banden en data-requirements")
    add_body(doc, "REACH hanteert de volgende tonnage-banden met oplopende data-vereisten:")
    tonnage = [
        ("1–10 ton/jaar", "Bijlage VII", "Basisfysicochemisch, toxicologisch (huid/oog irritatie, sensibilisatie, mutageniteit in vitro), ecotoxicologisch"),
        ("10–100 ton/jaar", "Bijlage VII + VIII", "Uitgebreider: herhaalde blootstelling (28-dag), toxiciteit bij reproductie (screening), afbraak, bioaccumulatie"),
        ("100–1.000 ton/jaar", "Bijlage VII–IX", "Subchronische toxiciteit (90-dag), ontwikkelingstoxiciteit, lange-termijn ecotoxiciteit"),
        (">1.000 ton/jaar", "Bijlage VII–X", "Chronische toxiciteit, carcinogeniteit, volle PBT-beoordeling"),
    ]
    add_styled_table(doc, ["Tonnage-band", "Bijlage REACH", "Data-requirements (samenvatting)"], tonnage)
    doc.add_paragraph()

    add_subsection(doc, "6.3", "SME-voorzieningen")
    add_body(doc,
        "Als MKB-bedrijf kan PM gebruikmaken van de ECHA-ondersteuning voor KMO's, waaronder "
        "vereenvoudigde registratieprocedures en de mogelijkheid om een vertegenwoordiger aan te "
        "stellen. ECHA biedt ook een gratis IT-tool (IUCLID) voor het opstellen van registratiedossiers. "
        "(Veiligheid van chemische stoffen in uw bedrijf — Inleiding voor KMO's, §2; ECHA "
        "Registratiegids v4.0, §1.7)"
    )

    # ── 7. SVHC-Analyse ──
    add_section(doc, "7", "SVHC-Analyse")
    add_body(doc,
        "SVHC's (Substances of Very High Concern) zijn stoffen die ernstige en vaak onomkeerbare "
        "effecten kunnen hebben op de menselijke gezondheid of het milieu. Criteria: CMR (categorie 1A/1B), "
        "PBT, vPvB, of equivalente zorgwekkende eigenschappen. (SVHC Guidance v2.1, §1.1–1.2)"
    )
    add_body(doc, "Relevantie voor Phoenix Metals:")
    add_bullet(doc, "V₂O₅ (vanadiumpentoxide): Opgenomen op de ECHA-kandidatenlijst. PM moet controleren of de concentratie in het uitgaande product >0,1% (w/w) bedraagt. Zo ja: communicatieverplichting naar downstream gebruikers en consumenten (indien van toepassing). (SVHC Guidance v2.1, §2.3)")
    add_bullet(doc, "Vanadiumverbindingen: Verschillende vanadiumverbindingen zijn geïdentificeerd als potentieel CMR (H341 – vermoedelijk mutageen). PM moet de SVHC-status van alle vanadiumspecies in het eindproduct monitoren. (SVHC Guidance v2.1, §3.1)")
    add_bullet(doc, "Nikkelsporen: De SARU ash bevat nikkeloxide (Fact Sheet Ash, §1). Nikkel en nikkelverbindingen zijn bekende SVHC's (carcinogeen Cat. 1A). PM moet aantonen dat nikkel in het eindproduct onder de 0,1%-drempel blijft. (Fact Sheet Ash 2025, §1; SVHC Guidance v2.1, §2.3)")
    add_body(doc,
        "Monitoring-verplichting: PM dient de ECHA-kandidatenlijst minimaal tweemaal per jaar te "
        "raadplegen en de Chemicals Master bij te werken. (Chemicals Master v2.1.0; SVHC Guidance v2.1, §4)"
    )

    # ── 8. Datadeling ──
    add_section(doc, "8", "Datadeling — SIEF en Consortium")
    add_body(doc,
        "REACH artikel 26 verplicht (potentiële) registranten om deel te nemen aan een SIEF "
        "(Substance Information Exchange Forum) voor stoffen die vooraf zijn geregistreerd. In een "
        "SIEF delen deelnemers bestaande data en verdelen zij de kosten van nieuwe testen. "
        "(Richtsnoer Gezamenlijk Gebruik van Gegevens v4.1, §1.2)"
    )
    add_body(doc, "Voor PM:")
    add_bullet(doc, "H₂SO₄: Al breed geregistreerd; PM kan aansluiten bij het bestaande SIEF/consortium. (Data Sharing Guidance v4.1, §2.1)")
    add_bullet(doc, "NaOH: Idem — breed geregistreerd, bestaand SIEF beschikbaar. (Data Sharing Guidance v4.1, §2.1)")
    add_bullet(doc, "Vanadiumelektrolyt (UVCB): Geen bestaand SIEF. PM moet zelf een dossier opbouwen of een nieuw SIEF initiëren indien andere partijen dezelfde stof produceren. (Data Sharing Guidance v4.1, §3.1)")
    add_bullet(doc, "V₂O₅: Bestaand SIEF beschikbaar via ECHA. (Data Sharing Guidance v4.1, §2.2)")
    add_body(doc,
        "Kostenverdeling: PM dient een 'Letter of Access' of 'Data Sharing Agreement' af te sluiten "
        "met bestaande registranten voor de stoffen die reeds zijn geregistreerd. (Data Sharing "
        "Guidance v4.1, §4.2)"
    )

    # ── 9. Autorisatie ──
    add_section(doc, "9", "Autorisatie — SRPV-Relevantie")
    add_body(doc,
        "Het REACH-autorisatieproces (Titel VII) is van toepassing op SVHC's die zijn opgenomen in "
        "Bijlage XIV. Een bedrijf dat een dergelijke stof gebruikt, moet een autorisatieaanvraag "
        "indienen, tenzij het gebruik is vrijgesteld. (How to Apply for Authorisation, §1.1)"
    )
    add_body(doc,
        "Voor PM is autorisatie potentieel relevant indien: (a) vanadiumpentoxide (V₂O₅) wordt "
        "opgenomen in Bijlage XIV, of (b) andere vanadiumverbindingen in het proces SVHC-status "
        "krijgen en op de autorisatielijst worden geplaatst. In dat geval moet PM een aanvraag "
        "indienen op basis van een Socio-Economische Analyse (SEA) of een 'Suitability for Risk "
        "Management Measures' (SRPV)-route. (How to Apply for Authorisation, §2.1–2.3)"
    )
    add_body(doc,
        "Actie: Monitor de Bijlage XIV-lijst. Indien autorisatie vereist wordt, start dan minimaal "
        "18 maanden voor de deadline ('sunset date') met de voorbereiding van een aanvraag. "
        "(How to Apply for Authorisation, §1.2)"
    )

    # ── 10. CLH-procedure ──
    add_section(doc, "10", "CLH-procedure — Vanadiumverbindingen")
    add_body(doc,
        "De CLH-procedure (Classification, Labelling and Packaging — Harmonised Classification) "
        "leidt tot een EU-brede geharmoniseerde classificatie voor stoffen die bijzondere zorg "
        "vereisen, met name CMR-stoffen. Een lidstaat of ECHA kan een CLH-voorstel indienen. "
        "(How to Submit a CLH Dossier, §1.2–1.3)"
    )
    add_body(doc,
        "Voor PM is dit relevant omdat vanadiumverbindingen momenteel onderwerp zijn van "
        "evaluatie. Indien een geharmoniseerde classificatie wordt vastgesteld, moet PM zijn "
        "zelfclassificatie aanpassen en de etikettering van het eindproduct wijzigen. Dit kan ook "
        "gevolgen hebben voor de SVHC-status en autorisatievereisten. (How to Submit a CLH "
        "Dossier, §2.1; CLP Basisgids, §3)"
    )

    # ── 11. Vergunningeisen ──
    add_section(doc, "11", "Vergunningeisen")

    add_subsection(doc, "11.1", "Omgevingsvergunning")
    add_body(doc,
        "De pilot plant op de Westerduinweg 3 te IJmuiden vereist een omgevingsvergunning "
        "milieubelastende activiteit. Op basis van het vooroverleg met OD IJmond (23 september 2023) "
        "is vastgesteld dat de pilotfase (80–120 ton/jaar) waarschijnlijk niet kwalificeert als 'chemische "
        "industrie' in de zin van het RIE (hoofdstuk 4), gelet op de beperkte omvang. Echter, categorie "
        "2.5 en 2.6 van het RIE dienen te worden gecontroleerd. (Verslag vooroverleg, §RIE-activiteit; "
        "Haalbaarheidsstudie Arcadis V04, §2.2)"
    )

    add_subsection(doc, "11.2", "BRZO / Seveso")
    add_body(doc,
        "Het BRZO 2015 (Besluit Risico's Zware Ongevallen) implementeert de Seveso III-richtlijn. "
        "De toepasselijkheid hangt af van de hoeveelheden gevaarlijke stoffen op de locatie. Voor de "
        "pilotfase met beperkte hoeveelheden NaOH en H₂SO₄ is BRZO waarschijnlijk niet van "
        "toepassing. Bij opschaling naar commerciële productie (7.200 ton H₂SO₄/jaar) moet BRZO "
        "worden geëvalueerd. (BRZO Elementen en VBS overzicht; Haalbaarheidsstudie Arcadis V04, §2.3)"
    )

    add_subsection(doc, "11.3", "ADR-vervoer")
    add_body(doc,
        "De meeste door PM gebruikte en geproduceerde stoffen vallen onder ADR-klasse 8 "
        "(corrosieve stoffen). PM moet ervoor zorgen dat: (a) alle vervoerders beschikken over "
        "ADR-certificering, (b) de verpakking voldoet aan de PG II- of PG III-eisen, en (c) de "
        "documentatie compleet is (vrachtbrief, veiligheidsinformatieblad, instructieschrift). "
        "(Chemicals Master v2.1.0; Uitgangspuntendocument, §1)"
    )

    # ── 12. Supply Chain ──
    add_section(doc, "12", "Supply Chain — SDS- en Communicatieverplichtingen")

    add_subsection(doc, "12.1", "Veiligheidsinformatiebladen (SDS)")
    add_body(doc,
        "REACH artikel 31 verplicht leveranciers van gevaarlijke stoffen om een veiligheidsinformatieblad "
        "(SDS) te verstrekken. Een SDS bestaat uit 16 secties conform Bijlage II van REACH. Voor "
        "stoffen die boven de 10 ton/jaar worden geproduceerd, moet een uitgebreid SDS (e-SDS) met "
        "blootstellingsscenario's worden opgesteld. (Richtsnoer SDS v4.0, §1.1–1.2)"
    )
    add_body(doc, "PM moet SDS'en beschikbaar hebben voor:")
    add_bullet(doc, "Alle ingaande stoffen (verkregen van leveranciers: Carl Roth voor NaOH/H₂SO₄)")
    add_bullet(doc, "Het uitgaande product (vanadiumelektrolyt): PM moet zelf een SDS opstellen")
    add_bullet(doc, "Nevenproducten (gips, filtratiemateriaal): SDS indien deze als product worden afgezet")

    add_subsection(doc, "12.2", "Downstream gebruikers")
    add_body(doc,
        "Als downstream gebruiker (DU) van H₂SO₄, NaOH en V₂O₅ moet PM controleren of het "
        "gebruik is gedekt door de blootstellingsscenario's in de ontvangen SDS'en. Indien niet, "
        "moet PM een eigen Chemische Veiligheidsbeoordeling (CSA) uitvoeren of de leverancier "
        "verzoeken het blootstellingsscenario uit te breiden. (Wegwijzer 13 — Downstreamgebruikers, "
        "§1; SDS Guidance v4.0, §3.22)"
    )

    # ── 13. Strategisch Actieplan ──
    add_section(doc, "13", "Strategisch Actieplan — 8 Acties")
    add_body(doc,
        "Het onderstaande actieplan is gebaseerd op de analyse in dit kennisdossier en is gericht op "
        "het tijdig en compliant realiseren van de REACH-verplichtingen van Phoenix Metals."
    )

    actions = [
        ("A1", "Stofidentificatie & SIP ontwikkeling", "Q2 2026", "HSE Manager / Toxicoloog",
         "Ontwikkel SIP voor vanadiumelektrolyt (UVCB). Bepaal grenssamenstellingen en karak- teriseringsmethoden. (Bron 03, 07)"),
        ("A2", "EoW-dossier voorbereiding", "Q3 2026", "HSE Manager / Jurist",
         "Bereid een End-of-Waste dossier voor de uitgaande producten voor, inclusief aantoon- bare marktvraag en productkwaliteit. (Bron 01, 09)"),
        ("A3", "SIEF-lidmaatschap en datadeling", "Q2 2026", "HSE Manager",
         "Sluit aan bij bestaande SIEF's voor H₂SO₄, NaOH en V₂O₅. Sluit Data Sharing Agreements af. (Bron 13)"),
        ("A4", "Registratiedossier voorbereiden", "Q4 2026", "HSE Manager / Registrar",
         "Start IUCLID-dossier voor vanadiumelektrolyt. Verzamel Bijlage VII-data. Engageer een OR (Only Representative) indien nodig. (Bron 02)"),
        ("A5", "SVHC-monitoring systeem", "Q2 2026", "HSE Manager",
         "Implementeer kwartaalcontrole van de ECHA-kandidatenlijst. Werk Chemicals Master bij. (Bron 04, 26)"),
        ("A6", "SDS-ontwikkeling voor uitgaande producten", "Q3 2026", "HSE Manager / Milieuadviseur",
         "Stel SDS op voor vanadiumelektrolyt conform REACH Bijlage II. (Bron 05)"),
        ("A7", "Vergunningtraject initiëren", "Q2 2026", "Manager Operations / Arcadis",
         "Start omgevingsvergunningaanvraag via gemeente Velsen. Betrek BRZO-analyse bij opschaling. (Bron 39–41, 47)"),
        ("A8", "CLH- en autorisatiewake", "Q2 2026 (voortdurend)", "HSE Manager",
         "Monitor CLH-ontwikkelingen voor vanadiumverbindingen en autorisatielijst. (Bron 12, 14)"),
    ]
    add_styled_table(doc,
        ["Actie", "Titel", "Deadline", "Verantwoordelijke", "Details / Bronverwijzing"],
        actions
    )
    doc.add_paragraph()

    # ── 14. Referenties ──
    add_section(doc, "14", "Referenties")
    add_body(doc, "Alle in dit dossier geraadpleegde bronnen:")
    refs = [
        ("[01]", "REACH Basis — Kern REACH/CLP-kader, OSOR-principe, stofidentificatie, ECHA-rol, PCN/UFI"),
        ("[02]", "ECHA Richtsnoer voor Registratie, v4.0, augustus 2021 — Registratieplicht, vrijstellingen, tonnage-berekening"),
        ("[03]", "Richtsnoer voor identificatie en naamgeving van stoffen volgens REACH en CLP, v3.0, december 2023"),
        ("[04]", "Guidance on the preparation of an Annex XV dossier for SVHC identification, v2.1, oktober 2018"),
        ("[05]", "Richtsnoer voor het samenstellen van veiligheidsinformatiebladen, v4.0, december 2020"),
        ("[06]", "Veiligheid van chemische stoffen in uw bedrijf — Inleiding voor KMO's, ECHA 2015"),
        ("[07]", "Het voorbereiden en ontwikkelen van een stofidentiteitsprofiel (SIP), ECHA april 2018"),
        ("[08]", "Guidance on labelling and packaging (CLP), v4.2, maart 2021"),
        ("[09]", "Praktische Gids 13 — Downstreamgebruikers en blootstellingsscenario's, v2, mei 2016"),
        ("[10]", "Practical Guide 15 — Qualitative human health assessment, november 2012"),
        ("[11]", "Wegwijzer Gebruiken en melden van (Q)SAR's, v3.1, oktober 2016"),
        ("[12]", "How to submit a CLH dossier, ECHA juni 2022"),
        ("[13]", "Richtsnoer voor gezamenlijk gebruik van gegevens (SIEF/consortium), v4.1, december 2023"),
        ("[14]", "How to apply for authorisation, ECHA februari 2021"),
        ("[15]", "Basisgids Chemische Veiligheid — Begrijpen en Werken met CLP"),
        ("[16]", "Phoenix Metals — Motivatiebrief HSE Manager rol"),
        ("[17]", "Phoenix Metals — Voorbereidingsoverzicht (takenlijst)"),
        ("[18]", "Draft PvA opstart Phoenix R&D"),
        ("[19]", "Haalbaarheidsstudie Phoenix Metals IJmuiden, Arcadis, 1 september 2025"),
        ("[20]", "Block Flow Diagram — visueel procesoverzicht"),
        ("[21]", "PFD — 1 Mil Plant Process Overview, P2-PFD-001-01 Rev.03"),
        ("[22]", "Plant Layout — overzicht installatie-indeling"),
        ("[23–24]", "Demo Process VR — procesbeschrijving demoplant (26 stappen)"),
        ("[25]", "Demo Layout — visuele indeling demoplant"),
        ("[26]", "Registration Chemicals MASTER v2.1.0 — Chemische stoffen register"),
        ("[27]", "SDS Vanadiumconcentraat"),
        ("[28]", "SDS Sulfuric Acid 25–75%, RCI Labscan, juli 2021"),
        ("[29]", "SDS Sodium Hydroxide 50%, Millipore, juli 2024"),
        ("[30]", "Rapportage verdiepende RI&E Gevaarlijke stoffen 2021, v3.0"),
        ("[31]", "PE-240-01-NL — Procedure aanvraag/beoordeling gevaarlijke stoffen"),
        ("[32]", "Phoenix Metals HSE Policy-V1, 1 januari 2025"),
        ("[33]", "Phoenix Metals BNP-V1 — Bedrijfsnoodplan"),
        ("[34]", "PBM Matrix Phoenix Metals draft 1"),
        ("[35]", "PS-201-NL v1.0 — PBM beleid"),
        ("[36]", "RI&E Inventarisatie PhoenixMetals"),
        ("[37]", "RI&E Inventarisatie PhoenixMetals MKB"),
        ("[38]", "RI&E Action plan and follow up"),
        ("[39]", "Verslag vooroverleg Phoenix, OD IJmond, 23 september 2023"),
        ("[40]", "Haalbaarheidsstudie Phoenix Metals IJmuiden, Arcadis V04, 12 december 2025"),
        ("[41]", "Uitgangspuntendocument Phoenix Metals IJmuiden — logistiek model"),
        ("[42]", "Factsheet SARU Ash 2025, v1.0"),
        ("[43]", "HSEQ Instructies Plant One Rotterdam, HS-P-00A, revisie 09"),
        ("[44]", "Legal Compliance Phoenix Metals 2025"),
        ("[45]", "Register Milieu Wet- en Regelgeving, HSE-02-L010.00 rev.8"),
        ("[46]", "Environmental Aspects and Compliance Register"),
        ("[47]", "Overzicht Relatie BRZO Elementen en VBS 3"),
        ("[48]", "PE-202-01 v1 — Management of Change"),
        ("[49]", "PE-210-04-NL v14 — Document Control"),
        ("[50]", "HS-F-0003 — TRA Hulplijst formulier"),
        ("[51]", "HS-P-0008 — TRA Procedure"),
        ("[52]", "HS-P-0018 — PSSR Procedure"),
        ("[53]", "Training Exposure to Hazardous Chemicals, Phoenix Metals 2025"),
        ("[54]", "Training Ergonomics, Phoenix Metals 2025"),
        ("[55]", "Opleiding Matrix Phoenix Metals 2024, rev.1"),
    ]
    for ref_id, ref_desc in refs:
        add_bullet(doc, f"{ref_id}: {ref_desc}")

    # Save
    path = os.path.join(OUTPUT_DIR, "REACH_Kennisdossier_Phoenix_Metals_D1_v3.0.docx")
    doc.save(path)
    return path


# ══════════════════════════════════════════════════════════════════════
# D2: VEILIG WERKEN HSEQ FRAMEWORK
# ══════════════════════════════════════════════════════════════════════

def generate_D2():
    doc = setup_document(
        "REACH VeiligWerken\nHSEQ Framework",
        "Gezondheid, Veiligheid & Milieu — Phoenix Metals"
    )

    # ── 1. Executive Summary ──
    add_section(doc, "1", "Executive Summary")
    add_body(doc,
        "Dit VeiligWerken HSEQ Framework beschrijft de risicobeheersmaatregelen voor het "
        "hydrometallurgisch extractieproces van Phoenix Metals. Het document integreert de REACH- "
        "en CLP-eisen met de operationele HSEQ-procedures van PM, inclusief RMM-hiërarchie, "
        "CLP-classificatie, PBM-matrix, noodprocedures en Arbowetgeving-koppeling. "
        "(HSE Policy-V1, §4; Chemische Veiligheid KMO's, §1)"
    )
    add_body(doc,
        "Kernrisico's: blootstelling aan H₂SO₄ (corrosief), NaOH (corrosief), vanadiumverbindingen "
        "(toxisch, potentieel CMR), en hitte/hoge temperatuur (80°C). Het framework is gebaseerd op "
        "de arbeidshygiënische strategie: bronmaatregelen → collectieve maatregelen → individuele "
        "maatregelen → PBM's. (PBM Beleid PS-201-NL, §4; Guide Chemical Safety SME, §2)"
    )

    # ── 2. Procesoverzicht ──
    add_section(doc, "2", "Procesoverzicht — 6 Stappen met Gevaren")
    add_body(doc,
        "Het PM-proces omvat zes hoofdprocesstappen, elk met specifieke gevaren. Het onderstaande "
        "overzicht is gebaseerd op de PFD (P2-PFD-001-01 Rev.03) en de demo-procesbeschrijving. "
        "(Bron 21, PFD; Bron 23–24, Demo Process VR)"
    )

    steps = [
        ("Stap 1: Dissolutie", "Ash/slak + NaOH + water → 80°C",
         "Chemisch: NaOH (H314), hitte (80°C), spatten, damp",
         "Gesloten reactor, automische dosering, afzuiging, koelsysteem"),
        ("Stap 2: Filtratie", "Scheiding filterkoek en filtraat",
         "Chemisch: heet filtraat (80°C), druk, NaOH-resten",
         "Gesloten filterunit, drukontlasting, koeling voor afvoer"),
        ("Stap 3: Kristallisatie", "Koeling filtraat → kristalvorming",
         "Chemisch: NaOH-resten, thermische schok",
         "Gecontroleerde koeling, isolatie, temperatuurmonitoring"),
        ("Stap 4: Zuurbehandeling", "Toevoeging H₂SO₄ + Al₂(SO₄)₃ → 80°C",
         "Chemisch: H₂SO₄ (H314, H290), exotherme reactie, H₂-gas, SO₂",
         "Gesloten reactor, langzame dosering, gasdetectie, scrubber"),
        ("Stap 5: Ion-exchange", "Filtratie + ion-exchange kolom",
         "Chemisch: H₂SO₄, regeneratie met 2,5M zuur",
         "Gesloten kolom, veiligheidskleppen, opvangbak"),
        ("Stap 6: Elektroreductie", "V(V) → V(IV) in elektrolysecel",
         "Elektrisch: gelijkstroom, elektrolyt (corrosief), H₂-vorming",
         "Galvanische scheiding, gasafvoer, isolatie, ATEX-apparatuur"),
    ]
    add_styled_table(doc,
        ["Processtap", "Beschrijving", "Gevaren", "Maatregelen"],
        steps
    )
    doc.add_paragraph()

    # ── 3. Chemisch Stoffenprofiel ──
    add_section(doc, "3", "Chemisch Stoffenprofiel")

    add_subsection(doc, "3.1", "Zwavelzuur (H₂SO₄)")
    add_body(doc,
        "Fysische eigenschappen: Vloeibaar, kleurloos tot lichtgeel, dichtheid ~1,4 g/cm³ (75%), "
        "kookpunt ~337°C (100%). Zeer corrosief bij contact met de meeste metalen. Exotherme "
        "reactie met water. (SDS Sulfuric Acid 25–75%, §9–10)"
    )
    add_body(doc,
        "Gevaren: Huidcorrosie Cat. 1A (H314), ernstig oogletsel Cat. 1 (H318), corrosief voor "
        "metalen Cat. 1 (H290). Bij verhitting: ontwikkeling van giftige dampen (SOₓ). Reactie met "
        "metalen kan waterstofgas vormen (explosiegevaar). (SDS Sulfuric Acid, §2–3; CLP Guidance v4.2, §2)"
    )

    add_subsection(doc, "3.2", "Natriumhydroxide (NaOH 50%)")
    add_body(doc,
        "Fysische eigenschappen: Vloeibare oplossing, kleurloos, dichtheid ~1,53 g/cm³. Sterke base. "
        "Exotherme reactie met zuren en water. (SDS NaOH 50%, §9–10)"
    )
    add_body(doc,
        "Gevaren: Huidcorrosie Cat. 1A (H314), ernstig oogletsel Cat. 1 (H318), corrosief voor "
        "metalen Cat. 1 (H290). Bij contact met water: sterke hitte-ontwikkeling. Contact met zuren "
        "leidt tot heftige exotherme reactie. (SDS NaOH 50%, §2–3)"
    )

    add_subsection(doc, "3.3", "Vanadiumconcentraat / Vanadiumelektrolyt")
    add_body(doc,
        "De vanadiumelektrolyt (V(IV) sulfaat oplossing) is een UVCB-stof met variabele samenstelling. "
        "De toxicologie is afhankelijk van de exacte samenstelling, maar vanadiumverbindingen zijn "
        "algemeen erkend als toxisch bij inademing (H331) en vermoedelijk mutageen (H341). "
        "(Stofidentificatiegids v3.0, §4.2; CLP Basisgids, §3)"
    )
    add_body(doc,
        "Toxicologie: Vanadium(V) verbindingen (V₂O₅) zijn geclassificeerd als toxisch bij inademing "
        "(H331), schadelijk bij inslikken (H302), en vermoedelijk mutageen (H341). Langdurige "
        "blootstelling kan leiden tot luchtwegirritatie, longschade en mogelijke carcinogene effecten. "
        "De vanadium(IV) verbindingen in de elektrolyt zijn minder toxisch maar vereisen nog steeds "
        "strikte blootstellingsbeheersing. (SDS Vanadiumconcentraat; SVHC Guidance v2.1, §3)"
    )

    # ── 4. RMM-Hiërarchie ──
    add_section(doc, "4", "RMM-Hiërarchie — RisicoBeheersMaatregelen")
    add_body(doc,
        "Phoenix Metals past de arbeidshygiënische strategie toe, conform het PBM-beleid (PS-201-NL) "
        "en de ECHA-richtsnoeren. De hiërarchie van maatregelen is als volgt: "
        "(PBM Beleid PS-201-NL, §4; Guide Chemical Safety SME, §3)"
    )

    rmm = [
        ("1. Bronmaatregelen", "Vervanging", "Substitutie van gevaarlijke stoffen door minder gevaarlijke alternatieven waar mogelijk. Voor PM: beperking V₂O₅-concentratie, gebruik van verdunde zuren."),
        ("2. Technische maatregelen", "Collectieve bescherming", "Gesloten reactoren, afzuiging bij open bewerkingen, gasdetectie (H₂, SO₂), scrubber, koelsystemen, drukontlasting, lekbakken/opleidingsystemen."),
        ("3. Organisatorische maatregelen", "Procedures en training", "Werkvergunningen, TRA (HS-P-0008), LMRA, MoC (PE-202-01), beperking blootstellingstijd, taakroulatie, instructie en training."),
        ("4. PBM's", "Individuele bescherming", "Laatste optie conform arbeidshygiënische strategie. PBM-matrix (FM-201-01-01) per taak/processtap. (PBM Beleid, §5)"),
    ]
    add_styled_table(doc, ["Niveau", "Type", "Toepassing Phoenix Metals"], rmm)
    doc.add_paragraph()

    # ── 5. CLP-Classificatie ──
    add_section(doc, "5", "CLP-Classificatie")
    add_body(doc,
        "De CLP-verordening (EG nr. 1272/2008) verplicht classificatie, etikettering en verpakking "
        "van alle gevaarlijke stoffen en mengsels. Onderstaande tabel toont de classificatie per "
        "PM-stof. (CLP Guidance v4.2, §2; CLP Basisgids, §3; SDS'en stofspecifiek)"
    )

    clp_data = [
        ("H₂SO₄ (25–75%)", "7664-93-9", "MetCorr1, SkinCorr1A, EyeDam1",
         "H290, H314, H318", "GHS05 (Corrosie)", "Gevaar"),
        ("NaOH (50%)", "1310-73-2", "MetCorr1, SkinCorr1A, EyeDam1",
         "H290, H314, H318", "GHS05 (Corrosie)", "Gevaar"),
        ("CaO", "1305-78-8", "SkinIrr2, EyeDam1, STOT SE3",
         "H315, H318, H335", "GHS05, GHS07", "Gevaar / Waarschuwing"),
        ("V₂O₅", "1314-62-1", "AcuteTox3*, Carc2, Repr2, Mut2*",
         "H331, H302, H341*, H351, H361", "GHS06, GHS08", "Gevaar"),
        ("Vanadiumelektrolyt (UVCB)", "N/A", "SkinCorr1A, AcuteTox4 (estimated)",
         "H314, H302 (est.)", "GHS05", "Gevaar"),
        ("Al₂(SO₄)₃·18H₂O", "7784-31-8", "Niet-geclassificeerd",
         "Geen H-zinnen", "Geen", "N.v.t."),
    ]
    add_styled_table(doc,
        ["Stof", "CAS", "Gevaarsklasse(n)", "H-zinnen", "Pictogram", "Signaalwoord"],
        clp_data
    )
    doc.add_paragraph()

    # ── 6. Gezondheidsbeoordeling ──
    add_section(doc, "6", "Gezondheidsbeoordeling — DNEL/DMEL en Blootstelling")
    add_body(doc,
        "REACH vereist dat registranten DNEL's (Derived No-Effect Levels) of DMEL's (Derived "
        "Minimal Effect Levels) afleiden voor elke blootslatingsroute. Voor PM zijn de volgende "
        "routes relevant: (Practical Guide 15, §1.2–1.3)"
    )
    add_bullet(doc, "Inhalatie: Primaire route voor vanadiumverbindingen (stof/damp) en H₂SO₄-mist")
    add_bullet(doc, "Huidcontact: Primaire route voor H₂SO₄ en NaOH (corrosief), en vanadiumelektrolyt")
    add_bullet(doc, "Inslikking: Secundaire route (onwaarschijnlijk bij correcte werkwijze)")

    add_body(doc,
        "Blootstellingsbeheersing: PM dient voor elke taak de blootstelling te kwantificeren en te "
        "vergelijken met de DNEL. Indien geen DNEL kan worden afgeleid (bijv. voor carcinogene "
        "effecten), moet een DMEL worden gebruikt of een kwalitatieve risicobeoordeling worden "
        "uitgevoerd. (Practical Guide 15, §2.1; Guide Chemical Safety SME, §4)"
    )

    # ── 7. PBM-Matrix ──
    add_section(doc, "7", "PBM-Matrix — per Taak/Processtap")
    add_body(doc,
        "De volgende PBM-matrix is gebaseerd op de PBM-beleidsdocumenten en de PBM-matrix "
        "van PM. De matrix geeft aan welke PBM's vereist zijn per processtap. (PBM Matrix draft 1; "
        "PBM Beleid PS-201-NL, §5)"
    )

    pbm = [
        ("Stap 1: Dissolutie (NaOH)", "X", "X", "X", "X", "O", "X"),
        ("Stap 2: Filtratie (heet)", "X", "X", "X", "X", "—", "X"),
        ("Stap 3: Kristallisatie", "X", "X", "X", "—", "—", "—"),
        ("Stap 4: Zuurbehandeling", "X", "X", "X", "X", "X", "X"),
        ("Stap 5: Ion-exchange", "X", "X", "X", "X", "—", "X"),
        ("Stap 6: Elektroreductie", "X", "X", "X", "X", "—", "—"),
        ("Algemeen (lopendeTaken)", "X", "—", "X", "—", "—", "—"),
    ]
    add_styled_table(doc,
        ["Taak/Processtap", "Veiligheidsbril", "Veiligheidshandschoenen (chemisch bestendig)", "Beschermende kleding", "Gezichtsscherm", "Adembescherming", "Veiligheidsschoenen"],
        pbm
    )
    doc.add_paragraph()
    add_body(doc, "X = Verplicht, O = Optioneel (bij specifieke handelingen), — = Niet vereist")
    add_body(doc,
        "Specifieke PBM-eisen per stof: NaOH — nitril handschoenen (Ansell 11-840 of equivalent), "
        "gezichtsscherm bij doseren. H₂SO₄ — chemisch bestendige handschoenen (Ansell Alphatec "
        "58-535B of equivalent), veiligheidsbril + gezichtsscherm. Vanadiumelektrolyt — FFP3 masker "
        "bij mogelijke aerosolvorming, chemisch bestendige handschoenen. (PBM Matrix draft 1; "
        "PBM Beleid PS-201-NL, §5)"
    )

    # ── 8. Noodprocedures ──
    add_section(doc, "8", "Noodprocedures")
    add_body(doc,
        "Het bedrijfsnoodplan (BNP-V1) van Phoenix Metals is afgestemd op het noodplan van "
        "Plant One Rotterdam (POR). Onderstaand een overzicht van de noodsituatiespecifieke "
        "procedures. (BNP-V1, §Inleiding; HSE Policy-V1, §4)"
    )

    add_subsection(doc, "8.1", "Lekkage / Morsing")
    add_bullet(doc, "Onmiddellijk: Stop de lekkagebron indien veilig. Alarmeer BHV via het POR-systeem.")
    add_bullet(doc, "H₂SO₄-morsing: Neutraliseren met NaHCO₃ of kalk. Absorberen met chemisch absorbent. Nooit water op geconcentreerd zuur!")
    add_bullet(doc, "NaOH-morsing: Verdunnen met veel water. Absorberen. Bescherming tegen spatten.")
    add_bullet(doc, "Vanadiumelektrolyt: Opvangen in lekbakken. Niet in het oppervlaktewater laten stromen. Afvoeren als gevaarlijk afval. (BNP-V1, §4)")

    add_subsection(doc, "8.2", "Brand")
    add_bullet(doc, "PM-proces gebruikt geen brandbare stoffen. Brandrisico is beperkt tot elektrische installaties en waterstofvorming bij zuur-metaalreacties.")
    add_bullet(doc, "Blusmiddelen: CO₂ of droge poeder voor elektrische branden. Geen water op zuurbranden.")
    add_bullet(doc, "Evacuatie: Volgens POR-evacuatieplan. Verzamelpunt conform BNP-V1. (BNP-V1, §5)")

    add_subsection(doc, "8.3", "Evacuatie")
    add_bullet(doc, "Alarm via POR-centrale. Ontruimingsleiders sturen medewerkers naar verzamelpunt.")
    add_bullet(doc, "BHV'ers leveren eerste hulp en controleren aanwezigheidslijst.")
    add_bullet(doc, "Externe hulpdiensten: Alarmnummer 112. Ambient Information POR. (BNP-V1, §3–5)")

    # ── 9. Arbowetgeving ──
    add_section(doc, "9", "Arbowetgeving")

    add_subsection(doc, "9.1", "CMR-stoffen")
    add_body(doc,
        "De Arbowet (art. 4.1c Arbobesluit) verplicht de werkgever om blootstelling aan CMR-stoffen "
        "te minimaliseren. Indien V₂O₅ of andere vanadiumverbindingen als CMR Cat. 1A/1B worden "
        "geclassificeerd, moet PM een vervangingsbeleid hanteren, technische maatregelen nemen en "
        "blootstelling registreren. (Rapportage RI&E Gevaarlijke stoffen v3.0, §CMR; Arbobesluit "
        "art. 4.1c)"
    )

    add_subsection(doc, "9.2", "MAC-waarden en Blootstellingslimieten")
    add_body(doc,
        "PM dient de wettelijke blootstellingslimieten (MAC-waarden / OEL's) voor alle gebruikte "
        "stoffen in acht te nemen. Vanadiumpentoxide heeft een wettelijke grenswaarde van "
        "0,25 mg/m³ (als V, 8-uur TWA). Zwavelzuurmist: 0,1 mg/m³ (TWA). NaOH-aerosol: "
        "1 mg/m³ (TWA). (RI&E Gevaarlijke stoffen v3.0, §Beoordeling; SER Grenswaardenlijst)"
    )

    add_subsection(doc, "9.3", "PAGO (Periodiek Arbeidsgezondheidsonderzoek)")
    add_body(doc,
        "Medewerkers die werken met gevaarlijke stoffen hebben recht op een PAGO, inclusief "
        "specifieke monitors voor longfunctie (vanadium/H₂SO₄), huid (NaOH/H₂SO₄) en "
        "blootstellingsregistratie. (Opleiding Matrix 2024, §Part 3; Arbowet art. 18)"
    )

    # ── 10. RI&E-koppeling ──
    add_section(doc, "10", "RI&E-koppeling")
    add_body(doc,
        "De RI&E van Phoenix Metals (algemeen en MKB) bevat meerdere items die direct gerelateerd "
        "zijn aan het werken met gevaarlijke stoffen. De RI&E-tox (verdiepende RI&E gevaarlijke "
        "stoffen) is uitgevoerd met Stoffenmanager®. De volgende knelpunten zijn geïdentificeerd: "
        "(RI&E Inventarisatie, §1–2; RI&E MKB, §1; RI&E Gevaarlijke stoffen v3.0, §Inventarisatie)"
    )

    rie_items = [
        ("Blootstelling gevaarlijke stoffen", "Hoog", "PBM's, afzuiging, gesloten systeem", "RMM per processtap (§4)"),
        ("Werken met corrosieve stoffen", "Hoog", "Technische maatregelen, training, PBM's", "CLP-classificatie (§5), PBM-matrix (§7)"),
        ("CMR-blootstelling (vanadium)", "Midden-Hoog", "Substitutie-onderzoek, blootstellingsbeheersing", "CMR-paragraaf (§9.1)"),
        ("BHV / Noodprocedures", "Midden", "BNP-V1 geïmplementeerd, trainingen", "Noodprocedures (§8)"),
        ("Ergonomie / tillen", "Laag-Midden", "Werkplekonderzoek, training", "Training Ergonomics (Bron 54)"),
        ("Beeldschermwerk", "Laag", "Werkplekinrichting", "RI&E Inventarisatie (Bron 36)"),
    ]
    add_styled_table(doc,
        ["RI&E-item", "Risiconiveau", "Maatregel", "Koppeling D2"],
        rie_items
    )
    doc.add_paragraph()

    # ── 11. Referenties ──
    add_section(doc, "11", "Referenties")
    add_body(doc, "Alle in dit framework geraadpleegde bronnen (identiek aan D1, §14):")
    refs = [
        "[01] REACH Basis — Kern REACH/CLP-kader",
        "[02] ECHA Richtsnoer voor Registratie v4.0, augustus 2021",
        "[03] Richtsnoer stofidentificatie en naamgeving v3.0, december 2023",
        "[04] SVHC Guidance v2.1, oktober 2018",
        "[05] Richtsnoer SDS v4.0, december 2020",
        "[06] Veiligheid chemische stoffen — Inleiding KMO's, ECHA 2015",
        "[07] SIP Praktische Gids, ECHA april 2018",
        "[08] CLP Guidance on Labelling and Packaging v4.2, maart 2021",
        "[09] Praktische Gids 13 — Downstreamgebruikers, v2, mei 2016",
        "[10] Practical Guide 15 — Qualitative Health Assessment, november 2012",
        "[11] QSAR Wegwijzer v3.1, oktober 2016",
        "[15] Basisgids Chemische Veiligheid — CLP",
        "[21] PFD — 1 Mil Plant Process Overview, P2-PFD-001-01 Rev.03",
        "[23–24] Demo Process VR — 26-stappen procesbeschrijving",
        "[26] Registration Chemicals MASTER v2.1.0",
        "[27] SDS Vanadiumconcentraat",
        "[28] SDS Sulfuric Acid 25–75%, juli 2021",
        "[29] SDS NaOH 50%, juli 2024",
        "[30] RI&E Gevaarlijke stoffen v3.0",
        "[31] PE-240-01-NL — Procedure gevaarlijke stoffen",
        "[32] HSE Policy-V1, 1 januari 2025",
        "[33] BNP-V1 — Bedrijfsnoodplan",
        "[34] PBM Matrix draft 1",
        "[35] PS-201-NL — PBM beleid",
        "[36] RI&E Inventarisatie PhoenixMetals",
        "[37] RI&E Inventarisatie MKB",
        "[38] RI&E Action plan and follow up",
        "[42] Factsheet SARU Ash 2025, v1.0",
        "[43] HSEQ Instructies Plant One Rotterdam, HS-P-00A",
        "[53] Training Exposure Hazardous Chemicals, 2025",
        "[54] Training Ergonomics, 2025",
        "[55] Opleiding Matrix 2024, rev.1",
    ]
    for ref in refs:
        add_bullet(doc, ref)

    # Save
    path = os.path.join(OUTPUT_DIR, "REACH_VeiligWerken_HSEQ_Framework_Phoenix_Metals_D2_v3.0.docx")
    doc.save(path)
    return path


# ──────────────────────────────────────────────────────────────────────
# MAIN
# ──────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    os.makedirs(OUTPUT_DIR, exist_ok=True)

    print("Genereren D1 v3.0...")
    d1_path = generate_D1()
    d1_size = os.path.getsize(d1_path)
    print(f"  → {d1_path} ({d1_size:,} bytes)")

    print("Genereren D2 v3.0...")
    d2_path = generate_D2()
    d2_size = os.path.getsize(d2_path)
    print(f"  → {d2_path} ({d2_size:,} bytes)")

    print(f"\nKlaar. D1: {d1_size:,} bytes | D2: {d2_size:,} bytes")
