#!/usr/bin/env python3
"""Generate DOC 4/12 Part A: Procedure Opslagveiligheid — Phoenix Metals IJmuiden."""

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

# Paths
LOGO = "/root/projects/jg/2026-pgs15-phoenix-metals/assets/branding/jvg-consultancy-logo.jpg"
OUT  = "/root/projects/jg/2026-pgs15-phoenix-metals/working/map/doc04_partA.docx"

doc = Document()

# ── Styles ──────────────────────────────────────────────────────────────
style = doc.styles['Normal']
style.font.name = 'Calibri'
style.font.size = Pt(11)
style.font.color.rgb = RGBColor(0x1F, 0x29, 0x37)
style.paragraph_format.space_after = Pt(6)
style.paragraph_format.line_spacing = 1.15

for level, size, color in [(1,14,0x003366),(2,13,0x003366),(3,12,0x003366),(4,11,0x003366)]:
    h = doc.styles[f'Heading {level}']
    h.font.name = 'Calibri'
    h.font.size = Pt(size)
    h.font.bold = True
    h.font.color.rgb = RGBColor((color>>16)&0xFF, (color>>8)&0xFF, color&0xFF)

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

def add_header_row(table, texts):
    row = table.rows[0]
    for i, txt in enumerate(texts):
        cell = row.cells[i]
        cell.text = ''
        p = cell.paragraphs[0]
        run = p.add_run(txt)
        run.bold = True
        run.font.color.rgb = RGBColor(0xFF,0xFF,0xFF)
        run.font.size = Pt(10)
        run.font.name = 'Calibri'
        p.alignment = WD_ALIGN_PARAGRAPH.CENTER
        set_cell_shading(cell, '003366')

def add_table(doc, headers, rows):
    table = doc.add_table(rows=1+len(rows), cols=len(headers))
    table.style = 'Table Grid'
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    add_header_row(table, headers)
    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 = ''
            p = cell.paragraphs[0]
            run = p.add_run(str(val))
            run.font.size = Pt(10)
            run.font.name = 'Calibri'
            if r_idx % 2 == 1:
                set_cell_shading(cell, 'F8F9FA')
    return table

# ── VOORBLAD ────────────────────────────────────────────────────────────
doc.add_paragraph()  # spacer

# Logo
if os.path.exists(LOGO):
    doc.add_picture(LOGO, width=Cm(4.0))
    last = doc.paragraphs[-1]
    last.alignment = WD_ALIGN_PARAGRAPH.CENTER

doc.add_paragraph()
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('PROCEDURE OPSLAGVEILIGHEID\nGEVAARLIJKE STOFFEN')
run.bold = True
run.font.size = Pt(22)
run.font.color.rgb = RGBColor(0x00,0x33,0x66)
run.font.name = 'Calibri'

p2 = doc.add_paragraph()
p2.alignment = WD_ALIGN_PARAGRAPH.CENTER
run2 = p2.add_run('Phoenix Metals IJmuiden')
run2.font.size = Pt(16)
run2.font.color.rgb = RGBColor(0x37,0x41,0x51)
run2.font.name = 'Calibri'

doc.add_paragraph()

# Meta-data tabel
add_table(doc,
    ['Parameter', 'Waarde'],
    [
        ['Documenttype', 'Procedure — Opslagveiligheid Gevaarlijke Stoffen'],
        ['Project', '2026-pgs15-phoenix-metals'],
        ['Locatie', 'Phoenix Metals IJmuiden (pilotfaciliteit)'],
        ['Versie', '1.0 (Concept)'],
        ['Datum', '26 april 2026'],
        ['Auteur', 'Kas (Director of Operations) — JvG Consultancy'],
        ['Classificatie', 'Vertrouwelijk — Alleen intern gebruik'],
        ['Geldigheid', 'Onbepaald — jaarlijkse herziening vereist'],
        ['Referentie', 'PGS 15:2025, Bijlage E, Tabel 9'],
    ])

doc.add_paragraph()
doc.add_heading('Goedkeuring', level=3)
add_table(doc,
    ['Rol', 'Naam', 'Datum', 'Handtekening'],
    [
        ['HSEQ Manager', '[Naam]', '', ''],
        ['Lab Manager', '[Naam]', '', ''],
        ['Directie', '[Naam]', '', ''],
    ])

doc.add_paragraph()
p3 = doc.add_paragraph()
run3 = p3.add_run('VERTROUWELIJKHEIDSCLAUSULE')
run3.bold = True
run3.font.size = Pt(10)
run3.font.color.rgb = RGBColor(0x00,0x33,0x66)
doc.add_paragraph(
    'Dit document is vertrouwelijk en uitsluitend bestemd voor geautoriseerde medewerkers van Phoenix Metals IJmuiden en JvG Consultancy. '
    'Reproductie, distributie of openbaarmaking zonder schriftelijke toestemming van de HSEQ Manager is verboden. '
    'Dit document bevat bedrijfsvertrouwelijke informatie over de opslag van gevaarlijke stoffen en gerelateerde risicobeheersmaatregelen.'
)

doc.add_page_break()

# ── H1: DOEL ────────────────────────────────────────────────────────────
doc.add_heading('1. Doel', level=1)

doc.add_paragraph(
    'Deze procedure definieert de veiligheidsmaatregelen voor de opslag van gevaarlijke stoffen bij Phoenix Metals IJmuiden. '
    'Het doel is het waarborgen van een veilige opslagconfiguratie die voldoet aan de eisen van PGS 15:2025 (Publicatiereeks Gevaarlijke Stoffen), '
    'het Besluit activiteiten leefomgeving (Bal), en de Arbowetgeving. De procedure is het primaire stuurdocument voor alle opslagactiviteiten '
    'op de pilotfaciliteit van Phoenix Metals en vormt de basis voor een aangetoonde compliant opslagpraktijk.'
)

doc.add_paragraph(
    'PGS 15:2025 is de norm voor de veilige opslag van verpakte gevaarlijke stoffen. De richtlijn bevat maatregelen op het gebied van '
    'stoffscheiding, vloeistofopvang, brandpreventie, ventilatie en personeelsdeskundigheid. Voor Phoenix Metals, met een totaalvolume van '
    'circa 300 liter ADR-klasse 8 (bijtende) stoffen en 15 kg niet-ADR-goederen, geldt het basisveiligheidsniveau. '
    'De stoffscheidingseis (Tabel 9, Bijlage E) geldt ongeacht het veiligheidsniveau en is de kritieke nalevingsmaatregel.'
)

doc.add_paragraph(
    'Toepassingsgebied: deze procedure is van toepassing op alle opslag van gevaarlijke stoffen binnen de Phoenix Metals faciliteit te IJmuiden, '
    'inclusief het storage racking systeem aan de voorzijde van het laboratorium. De doelgroep omvat alle medewerkers, laboranten, '
    'contractanten en bezoekers die betrokken zijn bij of toegang hebben tot opslaglocaties van gevaarlijke stoffen. '
    'De geldigheid is onbepaald met een verplichte jaarlijkse herziening of bij wijziging van het chemisch register.'
)

doc.add_paragraph(
    'De procedure is opgebouwd uit vijf hoofdstukken: doel en reikwijdte (H1), definities (H2), verantwoordelijkheden (H3), '
    'opslagconfiguratie (H4) en opvang/scheiding (H5). Samen vormen zij het operationele kader voor een PGS 15-compliant opslagpraktijk. '
    'Aanvullende documenten (risico-inventarisatie, calamiteitenplan, SDS-documentatie) zijn opgenomen in het bijbehorende dossier.'
)

# ── H2: DEFINITIES ──────────────────────────────────────────────────────
doc.add_heading('2. Definities', level=1)

doc.add_paragraph(
    'Onderstaande tabel definieert de kernbegrippen die in deze procedure worden gehanteerd. '
    'De definities zijn ontleend aan PGS 15:2025, het ADR, de CLP-Verordening en relevante NEN-normen.'
)

add_table(doc,
    ['Term', 'Definitie'],
    [
        ['Opslagvoorziening', 'Een daartoe bestemd gebouw, ruimte of terreindeel waar gevaarlijke stoffen worden opgeslagen (PGS 15 §1.3).'],
        ['Brandcompartiment', 'Een ruimte of gedeelte van een gebouw, omgeven door brandwerende scheidingen met voldoende brandweerstand (minimaal 30 minuten).'],
        ['Vak', 'Een gedeelte van een opslagvoorziening dat door ligging of markering als zodanig herkenbaar is afgescheiden.'],
        ['Werkvoorraad', 'De maximale hoeveelheid gevaarlijke stoffen die in een opslagvoorziening of werkruimte aanwezig mag zijn (PGS 15 M14).'],
        ['Lekbak', 'Een opvangvoorziening voor lekkage van vloeibare gevaarlijke stoffen, met een capaciteit van minimaal 110% van het volume van de grootste verpakking.'],
        ['VBB', 'Vaste Blusinstallatie — automatisch of semi-automatisch blussysteem voor opslagruimten (vereist bij veiligheidsniveau A, PGS 15 M96).'],
        ['UPD', 'Un Packaging Designation — UN-goedgekeurde verpakking voor het vervoer van gevaarlijke stoffen.'],
        ['SDS', 'Safety Data Sheet (Veiligheidsinformatieblad) — document met veiligheidsinformatie over een stof volgens REACH Bijlage II.'],
        ['ADR-klasse', 'Classificatie van gevaarlijke stoffen volgens het Europese Accord voor het vervoer van gevaarlijke stoffen over de weg.'],
        ['PG (Verpakkingsgroep)', 'Indicatie van het gevaarniveau: PG I (hoog), PG II (medium), PG III (laag).'],
        ['Compatibiliteit', 'De mate waarin twee of meer gevaarlijke stoffen veilig in elkaars nabijheid kunnen worden opgeslagen.'],
        ['Tabel 9', 'Compatibiliteitsmatrix uit PGS 15 Bijlage E die de vereiste scheiding tussen ADR-klassen aangeeft (V/B/A).'],
        ['A-scheiding', 'Scheiding in apart brandcompartiment of 5 meter vrije zone — strengste niveau.'],
        ['V-scheiding', 'Scheiding in aparte vakken binnen hetzelfde brandcompartiment.'],
        ['B-scheiding', 'Beoordeling vereist — scheiding tenzij VIB aantoont dat stoffen niet reageren.'],
        ['Wbdbo', 'Weerstand tegen branddoorbraak — de brandwerendheid van een constructie in minuten.'],
        ['CLP', 'Classification, Labelling and Packaging — EU-Verordening 1272/2008 voor classificatie en etikettering van stoffen.'],
    ])

# ── H3: VERANTWOORDELIJKHEDEN ───────────────────────────────────────────
doc.add_heading('3. Verantwoordelijkheden', level=1)

doc.add_paragraph(
    'De verantwoordelijkheden voor opslagveiligheid zijn verdeeld over vier kernrollen. Elke rol heeft specifieke taken, '
    'bevoegdheden en escalatieprocedures. De HSEQ Manager is eindverantwoordelijk voor naleving van deze procedure en de daaraan '
    'gekoppelde PGS 15-eisen. De Lab Manager is verantwoordelijk voor de dagelijkse uitvoering binnen het laboratorium. '
    'Medewerkers en contractanten dragen zorg voor correct gebruik en melden afwijkingen onmiddellijk.'
)

add_table(doc,
    ['Rol', 'Taken', 'Bevoegdheden', 'Escalatie'],
    [
        ['HSEQ Manager',
         '• Jaarlijkse herziening procedure\n• Goedkeuring wijzigingen chemisch register\n• Toezicht stoffscheiding compliance\n• Coördinatie audit/inspectie\n• Onderhoud SDS-documentatie',
         '• Goedkeuring nieuwe stoffen\n• Blokkering niet-compliance opslag\n• Stop-work bevoegdheid bij acuut risico\n• Contact hulpdiensten',
         '• Incidenten → Directie + hulpdiensten\n• Non-compliance → Lab Manager\n• Structurele tekorten → Directie (investering)'],
        ['Lab Manager',
         '• Dagelijks toezicht opslagpraktijk\n• Intake nieuwe stoffen (verificatie SDS)\n• Signalering schade/lekkage verpakkingen\n• Beheer werkvoorraad limieten\n• Instructie medewerkers',
         '• Weigering niet-goedgekeurde stoffen\n• Opdracht tot herindeling opslag\n• Toegangsbeheer opslagruimte',
         '• Lekkage/schade → HSEQ Manager\n• Grens overschreden → HSEQ Manager\n• Calamiteit → HSEQ Manager + 112'],
        ['Medewerker',
         '• Correct opslaan conform instructie\n• Visuele inspectie verpakkingen bij gebruik\n• Melden schade, lekkage, afwijkingen\n• Volgen werkvoorraad limieten',
         '• Stop-work bij onveilige situatie\n• Melden vialijn HSEQ/Lab Manager',
         '• Elke afwijking → Lab Manager direct\n• Acuut gevaar → 112 + Lab Manager'],
        ['Aannemer/Contractant',
         '• Naleven opslagregels bij uitvoering werk\n• Aanmelden gevaarlijke stoffen vooraf\n• Verwijderen eigen stoffen na afronding',
         '• Alleen vooraf goedgekeurde stoffen\n• Geen toegang zonder begeleiding',
         '• Via begeleidend personeel → Lab Manager'],
    ])

doc.add_paragraph(
    'Alle rollen zijn verplicht deel te nemen aan de jaarlijkse instructie opslagveiligheid (PGS 15 M85/M86). '
    'Nieuwe medewerkers ontvangen instructie bij indiensttreding. De HSEQ Manager documenteert deelname in het '
    'opleidingsregister. Bij niet-naleving door contractanten wordt de opdrachtgever (Directie) geïnformeerd en '
    'kan toegang worden ontzegd totdat compliantie is aangetoond.'
)

# ── H4: OPSLAGCONFIGURATIE ─────────────────────────────────────────────
doc.add_heading('4. Opslagconfiguratie', level=1)

doc.add_heading('4.1 Huidige situatie Phoenix Metals', level=2)
doc.add_paragraph(
    'De huidige opslagconfiguratie van Phoenix Metals IJmuiden bestaat uit één storage racking systeem aan de voorzijde '
    'van het laboratorium. Alle zes geregistreerde stoffen — natriumhydroxide 50% (100 liter), zwavelzuur 75% (30 liter), '
    'zwavelzuur 50% (70 liter), zwavelzuur 25% (100 liter), aluminiumsulfaat (5 kg) en calciumoxide (10 kg) — staan op '
    'hetzelfde rack zonder functionele scheiding. De totale hoeveelheid ADR-klasse 8 stoffen bedraagt circa 300 liter '
    '(ongeveer 390 kg), verdeeld over 18 jerrycans en 4 canisters.'
)

doc.add_paragraph(
    'De huidige configuratie is niet-compliant met PGS 15 Bijlage E, Tabel 9. De vereiste A-scheiding tussen natriumhydroxide '
    '(base) en zwavelzuur (zuur) ontbreekt. Beide stoffen staan in hetzelfde rack zonder fysieke scheiding, lekbakken of '
    'vakmarkering. Tevens is geen vloeistofopvang (lekbakken) gedocumenteerd en ontbreekt een formele werkvoorraadregeling. '
    'Calciumoxide (sterk basisch) staat eveneens in de nabijheid van zwavelzuur, wat eveneens A-scheiding vereist.'
)

doc.add_heading('4.2 Voorgestelde configuratie', level=2)
doc.add_paragraph(
    'De voorgestelde configuratie implementeert een zonale opslag met twee fysiek gescheiden zones binnen het bestaande rack-systeem. '
    'Zone 1 (Zuur-zone) huisvest alle zwavelzuurconcentraties (75%, 50%, 25%) en aluminiumsulfaat. Zone 2 (Base-zone) huisvest '
    'natriumhydroxide 50% en calciumoxide. De zones worden gescheiden door minimaal 2 meter vrije afstand, conform de E.3-uitzondering '
    'voor opslag onder 10.000 kg. Elke zone is voorzien van aparte lekbakken, vloermarkering en etikettering.'
)

doc.add_paragraph(
    'De zonale indeling is gebaseerd op de Tabel 9-compatibiliteitsmatrix. Binnen de zuur-zone zijn de drie zwavelzuurconcentraties '
    'compatibel (zelfde ADR-klasse 8, zelfde stof, geen scheiding vereist). Aluminiumsulfaat (niet-ADR) heeft een B-beoordeling '
    'ten opzichte van zwavelzuur: scheiding is aanbevolen maar kan worden beargumenteerd via VIB-analyse. '
    'In de base-zone zijn natriumhydroxide en calciumoxide compatibel (beide basisch, geen reactierisico).'
)

doc.add_heading('4.3 Lekbakken specificatie', level=2)
doc.add_paragraph(
    'Conform PGS 15 Maatregel 30 (M30) moet de vloeistofopvang-capaciteit minimaal 110% bedragen van het volume van de grootste '
    'enkele verpakking in de lekbak. Voor Phoenix Metals is de grootste verpakking een 25-liter jerrycan (natriumhydroxide 50% en '
    'zwavelzuur 25%). De vereiste lekbak-capaciteit per bak is derhalve minimaal 27,5 liter (25 × 1,10).'
)

doc.add_paragraph(
    'Praktische toewijzing: de zuur-zone ontvangt lekbakken met voldoende capaciteit voor de aanwezige jerrycans. Per 25-liter '
    'jerrycan één lekbak ≥27,5 liter; per cluster van kleinere jerrycans (10-liter) kan één grotere bak worden gebruikt mits '
    'de 110%-regel per individuele verpakking wordt gehaald. De base-zone ontvangt minimaal één lekbak ≥27,5 liter voor de '
    'natriumhydroxide-jerrycans. Lekbakken moeten bestand zijn tegen de opgeslagen stoffen (chemisch resistent, bijv. polyethyleen).'
)

doc.add_heading('4.4 Afstandsvereisten', level=2)
doc.add_paragraph(
    'De minimale afstand tussen de zuur-zone en base-zone bedraagt 2 meter vrije afstand. Dit is gebaseerd op de E.3-uitzondering '
    'in PGS 15 Bijlage E: bij een totale opslaghoeveelheid onder 10.000 kg (Phoenix Metals: ~390 kg) volstaat 2 meter vrije afstand '
    'tussen vakken als alternatief voor aparte brandcompartimenten of 5 meter vrije zone. De 2-meter afstand wordt gemeten tussen '
    'de buitenkanten van de respectievelijke lekbakken.'
)

doc.add_paragraph(
    'Indien de ruimtelijke configuratie van het rack-systeem onvoldoende afstand mogelijk maakt, kan worden gekozen voor een '
    'alternatieve scheiding: (a) een fysieke scheidingswand van minimaal 30 minuten brandwerendheid, of (b) een bufferzone gevuld '
    'met een goedgekeurde combinatiestof (inert materiaal) van 2 meter breedte. De gekozen oplossing wordt gedocumenteerd in de '
    'risico-inventarisatie en periodiek geïnspecteerd.'
)

doc.add_heading('4.5 Verpakkingseisen', level=2)
doc.add_paragraph(
    'Alle gevaarlijke stoffen worden opgeslagen in UN-goedgekeurde verpakkingen (UPD). Verpakkingen moeten intact zijn, '
    'geen zichtbare schade vertonen (deukken, corrosie, lekkage) en correct gesloten zijn tijdens opslag. Bij constatering '
    'van beschadiging wordt de verpakking onmiddellijk uit de opslag verwijderd en veiliggesteld in een geïmproviseerde '
    'lekopvang. De Lab Manager beoordeelt of herverpakking of afvoer noodzakelijk is.'
)

doc.add_paragraph(
    'Jerrycans en canisters worden rechtop opgeslagen, met de sluiting naar boven. Stapelen is alleen toegestaan indien de '
    'verpakkingen daartoe zijn ontworpen (UN-stapelcode). Maximaal drie lagen bij identieke verpakkingen. '
    'Alle verpakkingen dragen het oorspronkelijke etiket van de fabrikant. Zelfgeëtiketteerde of hergebruikte verpakkingen '
    'zijn verboden tenzij voorzien van een conforme CLP-etikettering.'
)

doc.add_heading('4.6 Etikettering', level=2)
doc.add_paragraph(
    'Etikettering van opgeslagen stoffen voldoet aan de CLP-Verordening (EG 1272/2008). Elk etiket toont: '
    'de stofnaam, CAS-nummer, GHS-pictogrammen, H-zinnen, P-zinnen en de naam/contactgegevens van de leverancier. '
    'Voor de opslaglocatie zelf geldt NEN-EN-ISO 20560 (veiligheidssignalering voor leidingen en opslagtanks): '
    'elke zone en elk vak is voorzien van duidelijke signalering met de relevante GHS-pictogrammen en een verwijzing '
    'naar het desbetreffende SDS.'
)

doc.add_paragraph(
    'De zuur-zone draagt de pictogrammen voor corrosie (GHS05) en exclamation mark (GHS07, afhankelijk van concentratie). '
    'De base-zone draagt GHS05 (corrosie) en, indien van toepassing, GHS07. Bovendien wordt een overzichtsbord geplaatst '
    'bij de ingang van de opslagruimte met een samenvatting van de aanwezige gevarenklassen en de locatie van de SDS-map. '
    'Etiketten worden maandelijks geïnspecteerd op leesbaarheid en actualiteit.'
)

# Configuratietabel
doc.add_heading('Overzicht: Huidige versus Gewenste Configuratie', level=3)
add_table(doc,
    ['Aspect', 'Huidige Situatie', 'Gewenste Situatie (Conform PGS 15)'],
    [
        ['Zonering', 'Geen — alles op één rack', '2 zones: zuur-zone en base-zone'],
        ['Scheiding NaOH / H₂SO₄', 'Geen (non-compliant)', 'A-scheiding via 2 m afstand (E.3)'],
        ['Lekbakken', 'Niet gedocumenteerd', 'Per zone, ≥110% grootste verpakking'],
        ['Vakmarkering', 'Geen', 'Vloertape/verf per zone + GHS-borden'],
        ['Etikettering', 'Fabrieksetiket only', 'CLP + NEN-EN-ISO 20560 signalering'],
        ['Calciumoxide', 'Naast H₂SO₄ (non-compliant)', 'Base-zone, gescheiden van H₂SO₄'],
        ['Aluminiumsulfaat', 'Geen specifieke positie', 'Zuur-zone, B-beoordeling gedocumenteerd'],
        ['SDS beschikbaarheid', 'Onbekend', 'Fysieke map + digitaal raadpleegbaar'],
        ['Werkvoorraad regeling', 'Niet formeel', 'Gedocumenteerd per zone (M14)'],
    ])

# ── H5: OPVANG EN SCHEIDING ────────────────────────────────────────────
doc.add_heading('5. Opvang en Scheiding', level=1)

doc.add_heading('5.1 Vloeistofopvang', level=2)
doc.add_paragraph(
    'De vloeistofopvang voor Phoenix Metals is gebaseerd op PGS 15 Maatregel 30 (M30). De opvangvoorziening (lekbak) '
    'moet voldoen aan de volgende eisen: (a) de capaciteit bedraagt minimaal 110% van het volume van de grootste verpakking '
    'in de bak; (b) het materiaal is bestand tegen de opgeslagen stoffen; (c) de bak is voorzien van een rooster of verhoging '
    'zodat de verpakking niet in gemorst product staat; (d) de bak wordt periodiek geïnspecteerd en geleegd bij constatering '
    'van vloeistof.'
)

doc.add_paragraph(
    'Voor de zuur-zone: de grootste verpakking is een 25-liter jerrycan (zwavelzuur 25%). Vereiste lekbak-capaciteit: '
    'minimaal 27,5 liter. Aanbevolen uitvoering: HDPE (high-density polyethylene) lekbak, chemisch resistent tegen '
    'zwavelzuur tot 75%. De bak moet voldoende afmetingen hebben om maximaal vier jerrycans van 25 liter of zeven jerrycans '
    'van 10 liter veilig te herbergen. Voor de base-zone: de grootste verpakking is eveneens een 25-liter jerrycan '
    '(natriumhydroxide 50%). Vereiste capaciteit: minimaal 27,5 liter per lekbak. Natriumhydroxide is bijtend voor '
    'veel materialen; de lekbak moet bestand zijn tegen sterke basen (HDPE of verzinkt staal met PE-inzet).'
)

doc.add_heading('5.2 Stoffenscheiding — Tabel 9', level=2)
doc.add_paragraph(
    'PGS 15 Bijlage E, Tabel 9, definieert de vereiste scheiding tussen stoffen van verschillende ADR-klassen. '
    'De scheidingniveaus zijn: A (apart brandcompartiment of 5 m vrije zone), B (beoordeling vereist) en '
    'V (aparte vakken). Voor Phoenix Metals zijn de relevante combinaties beperkt tot ADR-klasse 8 intern en '
    'ADR 8 versus niet-ADR stoffen.'
)

doc.add_paragraph(
    'De kritieke bevinding is dat Tabel 9 ADR-klasse 8 ↔ ADR-klasse 8 als A-scheiding classificeert. '
    'Dit betekent dat bijtende zuren en bijtende basen — hoewel beide ADR 8 — niet in hetzelfde vak mogen '
    'worden opgeslagen. De achterliggende reden is dat menging van een sterk zuur (H₂SO₄) en een sterke base (NaOH) '
    'leidt tot een heftige exotherme reactie met spatten en mogelijk het vrijkomen van corrosieve dampen. '
    'Deze reactie vormt een acuut risico voor medewerkers en de omgeving.'
)

doc.add_heading('5.3 A-scheiding: NaOH versus H₂SO₄', level=2)
doc.add_paragraph(
    'De A-scheiding tussen natriumhydroxide 50% en zwavelzuur (alle concentraties) is de belangrijkste veiligheidsmaatregel '
    'in deze procedure. De mengreactie NaOH + H₂SO₄ → Na₂SO₄ + H₂O is sterk exotherm. Bij concentraties van 50% respectievelijk '
    '25-75% leidt dit tot temperaturen boven 100°C met risico op kokend reactiemengsel, corrosieve spatten en dampvorming.'
)

doc.add_paragraph(
    'Implementatie bij Phoenix Metals: (a) fysieke scheiding van minimaal 2 meter vrije afstand tussen de zuur-zone en '
    'base-zone (E.3-uitzondering); (b) aparte lekbakken per zone om kruisbesmetting bij lekkage te voorkomen; '
    '(c) duidelijke markering van beide zones met tegengestelde signalering (zuur: rood etiket, base: blauw etiket); '
    '(d) verbod op gelijktijdig hanteren van stoffen uit beide zones in hetzelfde werkgebied zonder extra voorzorgsmaatregelen.'
)

doc.add_paragraph(
    'Alternatieven indien 2 meter afstand niet haalbaar: (a) plaatsing van een scheidingswand van minimaal 30 minuten '
    'brandwerendheid (bijv. gipsplaat met brandvertragende coating); (b) fysieke barrière van chemisch inert materiaal '
    '(bijv. zandbak of betonnen blok) van voldoende hoogte om lekkage op te vangen; (c) herconfiguratie van de opslag '
    'naar twee fysiek gescheiden locaties binnen het gebouw.'
)

doc.add_heading('5.4 Niet-ADR stoffen', level=2)
doc.add_paragraph(
    'Aluminiumsulfaat octadecahydraat (5 kg) en calciumoxide (10 kg) zijn niet-ADR-geclassificeerd. Desondanks gelden '
    'de scheidingseisen uit Tabel 9 ook voor deze stoffen in relatie tot ADR-klasse 8 stoffen. '
    'Aluminiumsulfaat is een zoutzuur-afgeleide die bij menging met sterke basen (NaOH) kan reageren. De Tabel 9-classificatie '
    'is B (beoordeling vereist). Plaatsing in de zuur-zone is acceptabel mits een VIB-analyse aantoont dat menging met '
    'zwavelzuur onder opslagcondities niet leidt tot gevaarlijke reacties.'
)

doc.add_paragraph(
    'Calciumoxide (CaO, 10 kg) is een sterk basisch oxide dat heftig reageert met zuren. De Tabel 9-classificatie '
    'ten opzichte van zwavelzuur is A (apart brandcompartiment). Calciumoxide wordt derhalve in de base-zone '
    'geplaatst, samen met natriumhydroxide. CaO reageert tevens met water onder warmteontwikkeling (blusmiddel: '
    'geen water, droog zand). Opslag dient droog en afgesloten te gebeuren. Contact met vocht wordt voorkomen '
    'door opslag in gesloten, vochtvrije verpakking (canister met deksel).'
)

doc.add_heading('5.5 Compatibiliteitsmatrix Phoenix Metals', level=2)
doc.add_paragraph(
    'Onderstaande matrix toont de specifieke compatibiliteitsrelaties tussen de zes stoffen in het chemisch register '
    'van Phoenix Metals. De classificatie is gebaseerd op Tabel 9 (PGS 15 Bijlage E) en substance-specifieke risicoanalyse.'
)

add_table(doc,
    ['Stof → / ↓', 'NaOH 50%', 'H₂SO₄ 75%', 'H₂SO₄ 50%', 'H₂SO₄ 25%', 'Al-sulfaat', 'CaO'],
    [
        ['NaOH 50%',     '—', 'A', 'A', 'A', 'B', '—'],
        ['H₂SO₄ 75%',    'A',  '—', '—', '—', 'B', 'A'],
        ['H₂SO₄ 50%',    'A',  '—', '—', '—', 'B', 'A'],
        ['H₂SO₄ 25%',    'A',  '—', '—', '—', 'B', 'A'],
        ['Al-sulfaat',   'B',  'B', 'B', 'B', '—', 'B'],
        ['CaO',          '—',  'A', 'A', 'A', 'B', '—'],
    ])

doc.add_paragraph()
doc.add_paragraph(
    'Legenda: A = Apart brandcompartiment / 5 m zone (of 2 m conform E.3); B = Beoordeling vereist (VIB-analyse); '
    '— = Geen scheiding vereist (compatibel). De matrix bevestigt dat NaOH en H₂SO₄ in alle concentraties '
    'A-scheiding vereisen. Calciumoxide en zwavelzuur vereisen eveneens A-scheiding. Aluminiumsulfaat vereist '
    'B-beoordeling ten opzichte van alle andere stoffen.'
)

# ── BRONNEN ─────────────────────────────────────────────────────────────
doc.add_heading('Bronnen', level=1)
doc.add_paragraph(
    '[1] PGS 15:2025 — Publicatiereeks Gevaarlijke Stoffen, Opslag van verpakte gevaarlijke stoffen, versie 1.0\n'
    '[2] META_DOSSIER_v1.0 — PGS-15 Compliance Phoenix Metals IJmuiden, 26 april 2026\n'
    '[3] CLP-Verordening (EG) Nr. 1272/2008, Bijlage I- V\n'
    '[4] REACH-Verordening (EG) Nr. 1907/2006\n'
    '[5] ADR 2025 — Accord européen relatif au transport international des marchandises dangereuses par route'
)

# ── Save ────────────────────────────────────────────────────────────────
doc.save(OUT)
print(f"Saved: {OUT}")
print(f"Size: {os.path.getsize(OUT)} bytes")

# Word count
full_text = []
for p in doc.paragraphs:
    full_text.append(p.text)
for t in doc.tables:
    for row in t.rows:
        for cell in row.cells:
            full_text.append(cell.text)
word_count = len(' '.join(full_text).split())
print(f"Word count: {word_count}")
