#!/usr/bin/env python3
"""REACH Kennisdossier — Presentatie Generator v1.0
Golden Standard: JvG Consultancy huisstijl
"""

from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE
import os, datetime

# ─── CONSTANTS ───
SLIDE_W = Inches(13.333)
SLIDE_H = Inches(7.5)
LOGO = "/root/projects/jg/assets/branding/jvg-logo-white-large.png"
DARK_BLUE = RGBColor(0x00, 0x33, 0x66)
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
TEXT_DARK = RGBColor(0x1F, 0x29, 0x37)
TEXT_SEC = RGBColor(0x37, 0x41, 0x51)
INFO_BLUE = RGBColor(0x3B, 0x82, 0xF6)
SUCCESS_GREEN = RGBColor(0x00, 0xA8, 0x59)
WARN_ORANGE = RGBColor(0xF5, 0x9E, 0x0B)
CRIT_ORANGE = RGBColor(0xFF, 0x6D, 0x00)
LIGHT_BG = RGBColor(0xF0, 0xF4, 0xF8)
BORDER_LIGHT = RGBColor(0xD1, 0xD5, 0xDB)

FONT = "Segoe UI"
FOOTER_TEXT = "JvG Consultancy | Safety • Governance • Advisory"

prs = Presentation()
prs.slide_width = SLIDE_W
prs.slide_height = SLIDE_H

# Use blank layout
blank_layout = prs.slide_layouts[6]

def add_header_bar(slide, title_text, subtitle_text=None):
    """Add dark blue header bar with title"""
    bar = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, SLIDE_W, Inches(1.1))
    bar.fill.solid()
    bar.fill.fore_color.rgb = DARK_BLUE
    bar.line.fill.background()
    # Title
    txBox = slide.shapes.add_textbox(Inches(0.6), Inches(0.15), Inches(10), Inches(0.7))
    tf = txBox.text_frame
    tf.word_wrap = True
    p = tf.paragraphs[0]
    p.text = title_text
    p.font.size = Pt(28)
    p.font.bold = True
    p.font.color.rgb = WHITE
    p.font.name = FONT
    if subtitle_text:
        p2 = tf.add_paragraph()
        p2.text = subtitle_text
        p2.font.size = Pt(14)
        p2.font.color.rgb = RGBColor(0xBB, 0xCC, 0xDD)
        p2.font.name = FONT
    # Logo top-right
    if os.path.exists(LOGO):
        slide.shapes.add_picture(LOGO, SLIDE_W - Inches(1.7), Inches(0.05), Inches(1.5), Inches(1.0))

def add_footer(slide, slide_num):
    """Add footer with logo, text, slide number"""
    # Footer bar
    bar = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, SLIDE_H - Inches(0.5), SLIDE_W, Inches(0.5))
    bar.fill.solid()
    bar.fill.fore_color.rgb = RGBColor(0xF8, 0xF9, 0xFA)
    bar.line.color.rgb = BORDER_LIGHT
    bar.line.width = Pt(0.5)
    # Logo small
    if os.path.exists(LOGO):
        # White bg rect behind logo
        wbg = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, Inches(0.1), SLIDE_H - Inches(0.45), Inches(0.85), Inches(0.4))
        wbg.fill.solid()
        wbg.fill.fore_color.rgb = WHITE
        wbg.line.fill.background()
        slide.shapes.add_picture(LOGO, Inches(0.15), SLIDE_H - Inches(0.43), Inches(0.75), Inches(0.37))
    # Center text
    txBox = slide.shapes.add_textbox(Inches(2), SLIDE_H - Inches(0.42), Inches(9), Inches(0.35))
    tf = txBox.text_frame
    p = tf.paragraphs[0]
    p.text = FOOTER_TEXT
    p.font.size = Pt(10)
    p.font.color.rgb = TEXT_SEC
    p.font.name = FONT
    p.alignment = PP_ALIGN.CENTER
    # Slide number
    txBox2 = slide.shapes.add_textbox(SLIDE_W - Inches(1), SLIDE_H - Inches(0.42), Inches(0.8), Inches(0.35))
    tf2 = txBox2.text_frame
    p2 = tf2.paragraphs[0]
    p2.text = str(slide_num)
    p2.font.size = Pt(10)
    p2.font.color.rgb = TEXT_SEC
    p2.font.name = FONT
    p2.alignment = PP_ALIGN.RIGHT

def add_card(slide, left, top, width, height, title, bullets, accent_color=DARK_BLUE, icon_text=None):
    """Add a content card with border and optional title"""
    card = slide.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, left, top, width, height)
    card.fill.solid()
    card.fill.fore_color.rgb = WHITE
    card.line.color.rgb = BORDER_LIGHT
    card.line.width = Pt(1)
    # Accent line on left
    accent = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, left, top + Inches(0.1), Inches(0.06), height - Inches(0.2))
    accent.fill.solid()
    accent.fill.fore_color.rgb = accent_color
    accent.line.fill.background()
    
    y_offset = top + Inches(0.15)
    if title:
        txBox = slide.shapes.add_textbox(left + Inches(0.25), y_offset, width - Inches(0.4), Inches(0.4))
        tf = txBox.text_frame
        tf.word_wrap = True
        p = tf.paragraphs[0]
        p.text = title
        p.font.size = Pt(16)
        p.font.bold = True
        p.font.color.rgb = accent_color
        p.font.name = FONT
        y_offset += Inches(0.4)
    
    if bullets:
        txBox2 = slide.shapes.add_textbox(left + Inches(0.25), y_offset, width - Inches(0.4), height - Inches(0.6))
        tf2 = txBox2.text_frame
        tf2.word_wrap = True
        for i, b in enumerate(bullets[:6]):
            if i == 0:
                p = tf2.paragraphs[0]
            else:
                p = tf2.add_paragraph()
            p.text = f"• {b}"
            p.font.size = Pt(13)
            p.font.color.rgb = TEXT_DARK
            p.font.name = FONT
            p.space_after = Pt(4)

def add_table(slide, left, top, width, rows_data, col_widths=None):
    """Add a styled table"""
    n_rows = len(rows_data)
    n_cols = len(rows_data[0])
    table_shape = slide.shapes.add_table(n_rows, n_cols, left, top, width, Inches(0.35 * n_rows))
    table = table_shape.table
    if col_widths:
        for i, w in enumerate(col_widths):
            table.columns[i].width = w
    for r_idx, row_data in enumerate(rows_data):
        for c_idx, cell_text in enumerate(row_data):
            cell = table.cell(r_idx, c_idx)
            cell.text = str(cell_text)
            for paragraph in cell.text_frame.paragraphs:
                paragraph.font.size = Pt(11)
                paragraph.font.name = FONT
                if r_idx == 0:
                    paragraph.font.bold = True
                    paragraph.font.color.rgb = WHITE
                    paragraph.font.size = Pt(12)
                else:
                    paragraph.font.color.rgb = TEXT_DARK
            if r_idx == 0:
                cell.fill.solid()
                cell.fill.fore_color.rgb = DARK_BLUE
            elif r_idx % 2 == 0:
                cell.fill.solid()
                cell.fill.fore_color.rgb = RGBColor(0xF0, 0xF4, 0xF8)
            else:
                cell.fill.solid()
                cell.fill.fore_color.rgb = WHITE
            cell.vertical_anchor = MSO_ANCHOR.MIDDLE
    return table

def add_kpi_card(slide, left, top, value, label, color=DARK_BLUE):
    """Add a KPI card with big number"""
    card = slide.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, left, top, Inches(2.8), Inches(1.4))
    card.fill.solid()
    card.fill.fore_color.rgb = WHITE
    card.line.color.rgb = BORDER_LIGHT
    card.line.width = Pt(1)
    # Top accent
    accent = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, left + Inches(0.1), top, Inches(2.6), Inches(0.06))
    accent.fill.solid()
    accent.fill.fore_color.rgb = color
    accent.line.fill.background()
    # Value
    txBox = slide.shapes.add_textbox(left + Inches(0.15), top + Inches(0.15), Inches(2.5), Inches(0.7))
    tf = txBox.text_frame
    p = tf.paragraphs[0]
    p.text = value
    p.font.size = Pt(28)
    p.font.bold = True
    p.font.color.rgb = color
    p.font.name = FONT
    p.alignment = PP_ALIGN.CENTER
    # Label
    txBox2 = slide.shapes.add_textbox(left + Inches(0.15), top + Inches(0.85), Inches(2.5), Inches(0.5))
    tf2 = txBox2.text_frame
    tf2.word_wrap = True
    p2 = tf2.paragraphs[0]
    p2.text = label
    p2.font.size = Pt(11)
    p2.font.color.rgb = TEXT_SEC
    p2.font.name = FONT
    p2.alignment = PP_ALIGN.CENTER

def add_callout(slide, left, top, width, text, border_color=WARN_ORANGE):
    """Add a callout box"""
    box = slide.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, left, top, width, Inches(0.7))
    box.fill.solid()
    box.fill.fore_color.rgb = RGBColor(0xFF, 0xFB, 0xEB)
    box.line.color.rgb = border_color
    box.line.width = Pt(2.5)
    txBox = slide.shapes.add_textbox(left + Inches(0.2), top + Inches(0.1), width - Inches(0.4), Inches(0.5))
    tf = txBox.text_frame
    tf.word_wrap = True
    p = tf.paragraphs[0]
    p.text = text
    p.font.size = Pt(13)
    p.font.color.rgb = TEXT_DARK
    p.font.name = FONT
    p.font.italic = True

slide_num = 0

# ═══════════════════════════════════════════════════════
# SLIDE 1: VOORBLAD
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
# Full dark blue background
bg = s.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, SLIDE_W, SLIDE_H)
bg.fill.solid()
bg.fill.fore_color.rgb = DARK_BLUE
bg.line.fill.background()
# Logo top-right
if os.path.exists(LOGO):
    s.shapes.add_picture(LOGO, SLIDE_W - Inches(2.0), Inches(0.5), Inches(1.5), Inches(1.35))
# Title
txBox = s.shapes.add_textbox(Inches(1), Inches(2.0), Inches(10), Inches(1.2))
tf = txBox.text_frame
tf.word_wrap = True
p = tf.paragraphs[0]
p.text = "REACH Kennisdossier"
p.font.size = Pt(44)
p.font.bold = True
p.font.color.rgb = WHITE
p.font.name = FONT
# Subtitle
txBox2 = s.shapes.add_textbox(Inches(1), Inches(3.3), Inches(9), Inches(1.0))
tf2 = txBox2.text_frame
tf2.word_wrap = True
p2 = tf2.paragraphs[0]
p2.text = "Registratie, Evaluatie, Autorisatie en Restrictie van Chemische Stoffen"
p2.font.size = Pt(22)
p2.font.color.rgb = RGBColor(0xBB, 0xCC, 0xDD)
p2.font.name = FONT
# Verordening
p3 = tf2.add_paragraph()
p3.text = "Verordening (EG) nr. 1907/2006"
p3.font.size = Pt(16)
p3.font.color.rgb = RGBColor(0x99, 0xAA, 0xBB)
p3.font.name = FONT
# Accent line
accent = s.shapes.add_shape(MSO_SHAPE.RECTANGLE, Inches(1), Inches(3.15), Inches(4), Inches(0.06))
accent.fill.solid()
accent.fill.fore_color.rgb = INFO_BLUE
accent.line.fill.background()
# Meta info
txBox3 = s.shapes.add_textbox(Inches(1), Inches(5.5), Inches(5), Inches(1.2))
tf3 = txBox3.text_frame
tf3.word_wrap = True
p4 = tf3.paragraphs[0]
p4.text = f"JvG Consultancy | April 2026 | Versie 1.0"
p4.font.size = Pt(14)
p4.font.color.rgb = RGBColor(0x88, 0x99, 0xAA)
p4.font.name = FONT
p5 = tf3.add_paragraph()
p5.text = "Case Study: Phoenix Metals IJmuiden"
p5.font.size = Pt(13)
p5.font.color.rgb = RGBColor(0x88, 0x99, 0xAA)
p5.font.name = FONT

# ═══════════════════════════════════════════════════════
# SLIDE 2: AGENDA
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Agenda")
add_footer(s, slide_num)

agenda_items = [
    ("01", "Introductie", "Wat is REACH, doelstellingen, scope"),
    ("02", "Kernproces REACH", "Registratie, evaluatie, stoffenidentificatie, SVHC"),
    ("03", "Autorisatie & Restrictie", "Bijlage XIV/XVII, SDS, data-deling"),
    ("04", "Praktijk & Actualiteit", "SCIP, UK REACH, Phoenix Metals case study"),
    ("05", "Key Takeaways", "Kernpunten en vervolgstappen"),
]
for i, (num, title, desc) in enumerate(agenda_items):
    y = Inches(1.5) + Inches(1.05) * i
    # Number circle
    circ = s.shapes.add_shape(MSO_SHAPE.OVAL, Inches(1), y, Inches(0.6), Inches(0.6))
    circ.fill.solid()
    circ.fill.fore_color.rgb = DARK_BLUE
    circ.line.fill.background()
    txb = s.shapes.add_textbox(Inches(1), y + Inches(0.1), Inches(0.6), Inches(0.4))
    txb.text_frame.paragraphs[0].text = num
    txb.text_frame.paragraphs[0].font.size = Pt(16)
    txb.text_frame.paragraphs[0].font.bold = True
    txb.text_frame.paragraphs[0].font.color.rgb = WHITE
    txb.text_frame.paragraphs[0].font.name = FONT
    txb.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
    # Title
    txb2 = s.shapes.add_textbox(Inches(1.9), y + Inches(0.02), Inches(5), Inches(0.35))
    txb2.text_frame.paragraphs[0].text = title
    txb2.text_frame.paragraphs[0].font.size = Pt(18)
    txb2.text_frame.paragraphs[0].font.bold = True
    txb2.text_frame.paragraphs[0].font.color.rgb = DARK_BLUE
    txb2.text_frame.paragraphs[0].font.name = FONT
    # Desc
    txb3 = s.shapes.add_textbox(Inches(1.9), y + Inches(0.38), Inches(8), Inches(0.3))
    txb3.text_frame.paragraphs[0].text = desc
    txb3.text_frame.paragraphs[0].font.size = Pt(13)
    txb3.text_frame.paragraphs[0].font.color.rgb = TEXT_SEC
    txb3.text_frame.paragraphs[0].font.name = FONT

# ═══════════════════════════════════════════════════════
# SLIDE 3: WAT IS REACH?
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Wat is REACH?")
add_footer(s, slide_num)

# Left card
add_card(s, Inches(0.5), Inches(1.4), Inches(5.8), Inches(2.8),
    "Verordening (EG) nr. 1907/2006", [
    "In werking getreden: 1 juni 2007",
    "Van toepassing in alle EU/EER-lidstaten",
    "\"No data, no market\" — de industrie bewijst veiligheid",
    "Verving 40+ bestaande chemische richtlijnen",
    "Beheerd door ECHA (Helsinki)"
], DARK_BLUE)

# Right card
add_card(s, Inches(6.8), Inches(1.4), Inches(5.8), Inches(2.8),
    "REACH = R-E-A-C-H", [
    "R — Registratie van stoffen ≥ 1 ton/jaar",
    "E — Evaluatie door ECHA en lidstaten",
    "A — Autorisatie voor SVHC's",
    "C — CHemische stoffen",
    "H — Restrictie van gevaarlijke stoffen"
], INFO_BLUE)

# KPI row
add_kpi_card(s, Inches(0.5), Inches(4.6), "2007", "In werking getreden", DARK_BLUE)
add_kpi_card(s, Inches(3.7), Inches(4.6), "40+", "Vervangen richtlijnen", INFO_BLUE)
add_kpi_card(s, Inches(6.9), Inches(4.6), "100.000+", "Geregistreerde stoffen", SUCCESS_GREEN)
add_kpi_card(s, Inches(10.1), Inches(4.6), "27", "EU-lidstaten + EER", WARN_ORANGE)

# ═══════════════════════════════════════════════════════
# SLIDE 4: WAAROM REACH BELANGRIJK IS
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Waarom REACH belangrijk is")
add_footer(s, slide_num)

add_card(s, Inches(0.5), Inches(1.4), Inches(3.8), Inches(2.5),
    "🛡️ Gezondheidsbescherming", [
    "Bescherming werknemers en consumenten",
    "Risicobeheersing blootstelling",
    "Verplichte risicobeoordelingen",
    "Preventie beroepsziekten"
], CRIT_ORANGE)

add_card(s, Inches(4.7), Inches(1.4), Inches(3.8), Inches(2.5),
    "🌍 Milieubescherming", [
    "Voorkoming bodem- en waterverontreiniging",
    "PBT/vPvB-stoffen strikt gereguleerd",
    "stimulans groene chemie",
    "Verplichte afvalbeheersing"
], SUCCESS_GREEN)

add_card(s, Inches(8.9), Inches(1.4), Inches(3.8), Inches(2.5),
    "🏛️ Markttoegang EU", [
    "\"No data, no market\" — geen registratie = geen verkoop",
    "Gelijke speelveld voor alle bedrijven",
    "Harmonisatie binnen EU/EER",
    "Internationale normering (GHS)"
], INFO_BLUE)

add_callout(s, Inches(0.5), Inches(4.3), Inches(12.3),
    "⚠️ Niet-naleving = boetes, marktuitsluiting en aansprakelijkheid bij ongevallen")

add_card(s, Inches(0.5), Inches(5.3), Inches(12.3), Inches(1.5),
    "Doelstellingen REACH", [
    "Bescherming menselijke gezondheid en milieu tegen chemische risico's",
    "Verbetering concurrentiepositie EU chemische industrie door innovatie",
    "Vrije handel in chemische stoffen binnen interne markt",
    "Bevordering alternatieve methoden (vermindering dierproeven)"
    ], DARK_BLUE)

# ═══════════════════════════════════════════════════════
# SLIDE 5: HET REACH PROCES (FLOW)
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Het REACH Proces — Overzicht")
add_footer(s, slide_num)

steps = [
    ("1. REGISTRATIE", "Stoffen ≥ 1 ton/jaar\nindienen bij ECHA", INFO_BLUE),
    ("2. EVALUATIE", "ECHA beoordeelt\nveiligheid dossier", SUCCESS_GREEN),
    ("3. AUTORISATIE", "SVHC's vereisen\nexpliciete toestemming", WARN_ORANGE),
    ("4. RESTRICTIE", "Beperking/verbod\ngevaarlijke stoffen", CRIT_ORANGE),
]

for i, (title, desc, color) in enumerate(steps):
    x = Inches(0.7) + Inches(3.1) * i
    y = Inches(1.8)
    # Box
    box = s.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, Inches(2.7), Inches(2.0))
    box.fill.solid()
    box.fill.fore_color.rgb = color
    box.line.fill.background()
    # Title
    txBox = s.shapes.add_textbox(x + Inches(0.15), y + Inches(0.2), Inches(2.4), Inches(0.5))
    tf = txBox.text_frame
    tf.word_wrap = True
    p = tf.paragraphs[0]
    p.text = title
    p.font.size = Pt(16)
    p.font.bold = True
    p.font.color.rgb = WHITE
    p.font.name = FONT
    p.alignment = PP_ALIGN.CENTER
    # Desc
    txBox2 = s.shapes.add_textbox(x + Inches(0.15), y + Inches(0.8), Inches(2.4), Inches(1.0))
    tf2 = txBox2.text_frame
    tf2.word_wrap = True
    p2 = tf2.paragraphs[0]
    p2.text = desc
    p2.font.size = Pt(13)
    p2.font.color.rgb = WHITE
    p2.font.name = FONT
    p2.alignment = PP_ALIGN.CENTER
    # Arrow (except last)
    if i < 3:
        arrow = s.shapes.add_shape(MSO_SHAPE.RIGHT_ARROW, x + Inches(2.75), y + Inches(0.7), Inches(0.35), Inches(0.5))
        arrow.fill.solid()
        arrow.fill.fore_color.rgb = DARK_BLUE
        arrow.line.fill.background()

# Bottom explanation
add_card(s, Inches(0.5), Inches(4.3), Inches(12.3), Inches(2.3),
    "Principe: \"No Data, No Market\"", [
    "De verantwoordelijkheid voor het aantonen van veiligheid ligt bij de industrie (fabrikanten/importeurs)",
    "Informatie over gevaren en risico's wordt doorgegeven in de toeleveringsketen via SDS",
    "Downstream gebruikers moeten hun gebruik rapporteren en risicobeheersmaatregelen toepassen",
    "ECHA coördineert; nationale overheden handhaven"
    ], DARK_BLUE)

# ═══════════════════════════════════════════════════════
# SLIDE 6: REGISTRATIE — Drempelwaarden
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Registratie — Drempelwaarden & Tonnagebands")
add_footer(s, slide_num)

data = [
    ["Tonnageband", "Informatie-eis", "CSR verplicht?", "Typische kosten"],
    ["1 — 10 ton/jaar", "Bijlage VII + aanvullend", "Nee (wel safe use)", "€5.000 — €15.000"],
    ["10 — 100 ton/jaar", "Bijlage VII + VIII + IX (ged.)", "Ja (incl. blootstellingsscenario's)", "€30.000 — €80.000"],
    ["100 — 1.000 ton/jaar", "Bijlage VII + VIII + IX + X", "Ja", "€80.000 — €200.000"],
    ["> 1.000 ton/jaar", "Volledige bijlagen VII — X", "Ja (volledig)", "€200.000 — €500.000+"],
]
add_table(s, Inches(0.5), Inches(1.4), Inches(12.3), data,
    [Inches(2.5), Inches(3.5), Inches(3.0), Inches(3.3)])

add_callout(s, Inches(0.5), Inches(3.8), Inches(12.3),
    "💡 Tip: Hoe hoger de tonnage, hoe uitgebreider de informatie-eisen en kosten — vroegtijdige planning is essentieel")

add_card(s, Inches(0.5), Inches(4.8), Inches(5.8), Inches(2.0),
    "Drempelwaarde", [
    "Registratieplicht geldt vanaf 1 ton/jaar per stof",
    "Per fabrikant of importeur afzonderlijk",
    "Tussenstoffen (art. 18): verlicht regime",
    "Monomeren in polymeren: volledige registratie"
    ], DARK_BLUE)

add_card(s, Inches(6.8), Inches(4.8), Inches(5.8), Inches(2.0),
    "Gevolgen niet-registratie", [
    "Stof mag niet op de markt worden gebracht",
    "Nationale handhaving: boetes en sancties",
    "Aansprakelijkheid bij ongevallen",
    "Reputatieschade en klantverlies"
    ], CRIT_ORANGE)

# ═══════════════════════════════════════════════════════
# SLIDE 7: REGISTRATIESTAPPEN
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Registratiestappen — Stap voor Stap")
add_footer(s, slide_num)

reg_steps = [
    ("1", "Stoffenidentificatie", "CAS-nummer, IUPAC-naam, samenstelling"),
    ("2", "Volumebepaling", "Jaarlijkse tonnage per stof berekenen"),
    ("3", "Gegevensverzameling", "Fysisch-chemische, tox. en ecotox. data"),
    ("4", "Data-deling (SIEF)", "Gegevens uitwisselen met andere registranten"),
    ("5", "Chemische Veiligheidsbeoordeling", "CSA/CSR bij ≥ 10 ton/jaar"),
    ("6", "Dossier in IUCLID", "Technisch dossier opstellen"),
    ("7", "Indiening REACH-IT", "Dossier indienen + registratiebijdrage"),
    ("8", "Bevestiging", "Registratienummer ontvangen van ECHA"),
]

for i, (num, title, desc) in enumerate(reg_steps):
    col = i % 2
    row = i // 2
    x = Inches(0.5) + Inches(6.4) * col
    y = Inches(1.4) + Inches(1.4) * row
    # Step number box
    sbox = s.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, Inches(0.5), Inches(0.5))
    sbox.fill.solid()
    sbox.fill.fore_color.rgb = DARK_BLUE if col == 0 else INFO_BLUE
    sbox.line.fill.background()
    stxb = s.shapes.add_textbox(x, y + Inches(0.08), Inches(0.5), Inches(0.35))
    stxb.text_frame.paragraphs[0].text = num
    stxb.text_frame.paragraphs[0].font.size = Pt(18)
    stxb.text_frame.paragraphs[0].font.bold = True
    stxb.text_frame.paragraphs[0].font.color.rgb = WHITE
    stxb.text_frame.paragraphs[0].font.name = FONT
    stxb.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
    # Title + desc
    ttxb = s.shapes.add_textbox(x + Inches(0.65), y + Inches(0.0), Inches(5.2), Inches(0.3))
    ttxb.text_frame.paragraphs[0].text = title
    ttxb.text_frame.paragraphs[0].font.size = Pt(15)
    ttxb.text_frame.paragraphs[0].font.bold = True
    ttxb.text_frame.paragraphs[0].font.color.rgb = DARK_BLUE
    ttxb.text_frame.paragraphs[0].font.name = FONT
    dtxb = s.shapes.add_textbox(x + Inches(0.65), y + Inches(0.35), Inches(5.2), Inches(0.8))
    dtxb.text_frame.word_wrap = True
    dtxb.text_frame.paragraphs[0].text = desc
    dtxb.text_frame.paragraphs[0].font.size = Pt(12)
    dtxb.text_frame.paragraphs[0].font.color.rgb = TEXT_SEC
    dtxb.text_frame.paragraphs[0].font.name = FONT

# ═══════════════════════════════════════════════════════
# SLIDE 8: STOFFENIDENTIFICATIE & CLASSIFICATIE
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Stoffenidentificatie & Classificatie")
add_footer(s, slide_num)

id_data = [
    ["Identificatiemiddel", "Beschrijving"],
    ["CAS-nummer", "Unieke numerieke identificatie (Chemical Abstracts Service)"],
    ["EC-nummer", "Europees identificatienummer (EINECS/ELINCS)"],
    ["IUPAC-naam", "Systematische chemische naam"],
    ["SMILES/InChI", "Structurele representaties molecuulstructuur"],
    ["Samenstelling", "Zuiverheid, bestanddelen, onzuiverheden"],
]
add_table(s, Inches(0.5), Inches(1.4), Inches(6.0), id_data,
    [Inches(2.2), Inches(3.8)])

# CLP gevaarsklassen
gc_data = [
    ["Gevaarsklasse", "Voorbeelden", "Signalwoord"],
    ["Fysieke gevaren", "Ontvlambaar, explosief, oxiderend", "Gevaar/Waarschuwing"],
    ["Gezondheidsgevaren", "Acute toxiciteit, CMR, sensibiliserend", "Gevaar/Waarschuwing"],
    ["Milieugevaren", "Aquatisch toxisch, ozonlaag", "Waarschuwing"],
]
add_table(s, Inches(6.8), Inches(1.4), Inches(6.0), gc_data,
    [Inches(2.0), Inches(2.5), Inches(1.5)])

# GHS pictogrammen
picto_data = [
    ["Pictogram", "Gevaar"],
    ["☠️ Schedel & botten", "Acute toxiciteit (cat. 1-3)"],
    ["🔥 Vlam", "Ontvlambaar"],
    ["💥 Onderslag", "Explosief"],
    ["⭕ Corrosie", "Corrosief / huidverbranding"],
    ["🧪 Gasfles", "Gas onder druk"],
    ["❗ Uitroepteken", "Irriterend, sensibiliserend"],
    ["🌍 Milieu", "Milieugevaarlijk"],
    ["👤 Borstkas", "Gezondheidsgevaar (specifieke doelorgaan)"],
    ["🔴 Vlam over cirkel", "Oxiderend"],
]
add_table(s, Inches(0.5), Inches(4.0), Inches(5.5), picto_data[:6],
    [Inches(2.5), Inches(3.0)])

# H-zinnen
hz_data = [
    ["Code", "Tekst"],
    ["H314", "Veroorzaakt ernstige huidverbrandingen en oogbeschadiging"],
    ["H331", "Giftig bij inademing"],
    ["H350", "Kan kanker veroorzaken"],
    ["P260", "Stof/gas/nevel/damp niet inademen"],
    ["P280", "Beschermende handschoenen/kleding/oogbescherming dragen"],
]
add_table(s, Inches(6.8), Inches(4.0), Inches(6.0), hz_data,
    [Inches(1.2), Inches(4.8)])

# ═══════════════════════════════════════════════════════
# SLIDE 9: SVHC & KANDIDAATLIJST
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "SVHC & Kandidaatlijst")
add_footer(s, slide_num)

add_card(s, Inches(0.5), Inches(1.4), Inches(6.0), Inches(2.5),
    "Wat zijn SVHC's? (Zeer Zorgwekkende Stoffen)", [
    "CMR — Carcinogeen, Mutageen, Reproductietoxisch (cat. 1A/1B)",
    "PBT — Persistent, Bioaccumulatief, Toxisch",
    "vPvB — Zeer persistent, Zeer bioaccumulatief",
    "Endocriene stoornissen en equivalente zorgniveau (art. 57(f))",
    "Kandidaatlijst bevat medio 2025 > 240 stoffen"
    ], CRIT_ORANGE)

add_card(s, Inches(6.8), Inches(1.4), Inches(6.0), Inches(2.5),
    "Art. 33 — Verplichtingen", [
    "SVHC > 0,1% in voorwerp → ontvanger informeren",
    "Consumenten hebben recht op informatie binnen 45 dagen",
    "Art. 7(2): Notificatie aan ECHA bij > 1 ton/jaar",
    "Weg naar Bijlage XIV (autorisatielijst) via Kandidaatlijst",
    "Sunset date → stof alleen nog met autorisatie"
    ], DARK_BLUE)

# Voorbeeldstoffen tabel
svhc_data = [
    ["Stof", "CAS", "Reden SVHC", "Status"],
    ["Chroom-6 verbindingen", "Divers", "CMR (carc. cat. 1B)", "Bijlage XIV"],
    ["Bisfenol A (BPA)", "80-05-7", "Endocriene stoornis", "Kandidaatlijst"],
    ["Lood (Pb)", "7439-92-1", "Reprotox cat. 1A", "Kandidaatlijst"],
    ["Asbest", "Divers", "Carcinogeen cat. 1A", "Bijlage XVII"],
    ["PFAS (bepaalde)", "Divers", "vPvB", "Kandidaatlijst / restrictie"],
]
add_table(s, Inches(0.5), Inches(4.2), Inches(12.3), svhc_data,
    [Inches(3.0), Inches(1.5), Inches(3.5), Inches(4.3)])

# ═══════════════════════════════════════════════════════
# SLIDE 10: EVALUATIE DOOR ECHA
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Evaluatie door ECHA")
add_footer(s, slide_num)

add_card(s, Inches(0.5), Inches(1.4), Inches(6.0), Inches(3.0),
    "Dossierbeoordeling", [
    "Compliance checks: controle technische volledigheid",
    "Testvoorstelbeoordeling: noodzaak dierproeven (art. 40)",
    "Derden hebben 45 dagen tijd voor alternatieve data",
    "ECHA kan aanvullende informatie eisen",
    "Doel: onnodige dierproeven voorkomen"
    ], INFO_BLUE)

add_card(s, Inches(6.8), Inches(1.4), Inches(6.0), Inches(3.0),
    "Stoffenbeoordeling", [
    "Lidstaten selecteren stoffen voor verdere beoordeling",
    "Criteria: vermoeden onaanvaardbare risico's",
    "Hoge volumes (hoge tonnagebands)",
    "Structuurverwantschap met bekende probleemstoffen",
    "Exposure van kwetsbare populaties"
    ], DARK_BLUE)

add_card(s, Inches(0.5), Inches(4.8), Inches(12.3), Inches(1.8),
    "Verplichtingen voor bedrijven", [
    "Registratiedossiers up-to-date houden (art. 22, UO 2020/1435)",
    "Coöperatief omgaan met testvoorstellen: alternatieven binnen 45 dagen",
    "Voldoen aan besluiten: aanvullende tests of risicobeheersing",
    "Bij veranderingen (volume, gevaren, toepassingen): dossier bijwerken"
    ], WARN_ORANGE)

# ═══════════════════════════════════════════════════════
# SLIDE 11: AUTORISATIE
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Autorisatie — Bijlage XIV")
add_footer(s, slide_num)

add_card(s, Inches(0.5), Inches(1.4), Inches(6.0), Inches(2.5),
    "Wanneer is autorisatie nodig?", [
    "Stof staat op Bijlage XIV (autorisatielijst)",
    "Vanaf sunset date: alleen gebruiken met autorisatie",
    "Aanvraag minimaal 18 maanden vóór sunset date",
    "Autorisatie is tijdelijk: 5 — 15 jaar"
    ], CRIT_ORANGE)

add_card(s, Inches(6.8), Inches(1.4), Inches(6.0), Inches(2.5),
    "Aanvraagproces", [
    "1. Verifieer stof op Bijlage XIV + sunset date",
    "2. Onderzoek alternatieven (Substitution Plan)",
    "3. Stel analyserapport op",
    "4. Dien aanvraag in via REACH-IT",
    "5. ECHA advies → Europese Commissie beslist"
    ], DARK_BLUE)

# Kosten
cost_data = [
    ["Post", "Kosten"],
    ["Voorbereiding analyserapport", "€50.000 — €150.000"],
    ["ECHA-verwerkingsbijdrage", "Tot €70.000+"],
    ["Doorlooptijd", "18 — 36 maanden"],
    ["Betrokkenheid", "5 — 15 jaar (verlenging mogelijk)"],
]
add_table(s, Inches(0.5), Inches(4.2), Inches(6.0), cost_data,
    [Inches(3.0), Inches(3.0)])

add_card(s, Inches(6.8), Inches(4.2), Inches(6.0), Inches(2.5),
    "Substitutie: het doel van autorisatie", [
    "Aantonen dat risico's adequaat beheerst zijn",
    "Onderzoeken of geschikte alternatieven bestaan",
    "Substitutieplan opstellen als alternatieven bestaan",
    "Motiveren waarom alternatieven niet worden toegepast"
    ], SUCCESS_GREEN)

# ═══════════════════════════════════════════════════════
# SLIDE 12: RESTRICTIE
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Restrictie — Bijlage XVII")
add_footer(s, slide_num)

add_card(s, Inches(0.5), Inches(1.4), Inches(5.8), Inches(2.0),
    "Wat is restrictie?", [
    "Beperking/verbod op vervaardiging, handel en gebruik",
    "Kan betrekking hebben op: stof, mengsel, voorwerp",
    "Specifieke toepassingen of gebruiksvormen",
    "Uitgebreid instrument ter bescherming gezondheid/milieu"
    ], DARK_BLUE)

add_card(s, Inches(6.8), Inches(1.4), Inches(5.8), Inches(2.0),
    "Restrictieproces", [
    "Lidstaat dient restrictiedossier in bij ECHA",
    "Openbare raadpleging: 6 maanden",
    "RAC + SEAC brengen advies uit",
    "Europese Commissie neemt definitief besluit"
    ], INFO_BLUE)

rest_data = [
    ["Stof", "Type restrictie", "Kenmerken"],
    ["Chroom-6", "Verbod (uitzonderingen)", "Diverse overgangsregelingen"],
    ["Asbest", "Verbod", "Verbod sinds 2005"],
    ["PFAS", "Universele restrictie (voorgesteld)", "In behandeling sinds 2023"],
    ["Lood", "Verbod (toepassingsafhankelijk)", "Max. concentratie 0,1%"],
    ["CMR cat. 1A/1B", "Verbod in consumentenproducten", "Uitzonderingen met toestemming"],
    ["Nikkel", "Beperking migratielimiet", "Max. 0,5 µg/cm²/week"],
]
add_table(s, Inches(0.5), Inches(3.8), Inches(12.3), rest_data,
    [Inches(2.5), Inches(4.5), Inches(5.3)])

# ═══════════════════════════════════════════════════════
# SLIDE 13: VEILIGHEIDSINFORMATIEBLADEN (SDS)
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Veiligheidsinformatiebladen (SDS)")
add_footer(s, slide_num)

sds_data = [
    ["Sectie", "Inhoud"],
    ["1", "Identificatie stof/mengsel en vennootschap"],
    ["2", "Mogelijke gevaren (classificatie, H/P-zinnen)"],
    ["3", "Samenstelling en bestanddelen"],
    ["4", "Eerste-hulpmaatregelen"],
    ["5", "Brandblusmaatregelen"],
    ["6", "Maatregelen bij onopzettelijke vrijgifte"],
    ["7", "Hanteren en opslaan"],
    ["8", "Blootstellingsbeheersing / PBM"],
    ["9", "Fysische en chemische eigenschappen"],
    ["10", "Stabiliteit en reactiviteit"],
    ["11", "Toxicologische informatie"],
    ["12", "Ecologische informatie"],
    ["13", "Afvoer van de stof"],
    ["14", "Vervoerinformatie (ADR/RID/IMDG)"],
    ["15", "Voorschriften (regelgeving)"],
    ["16", "Overige informatie"],
]
add_table(s, Inches(0.5), Inches(1.4), Inches(5.5), sds_data,
    [Inches(0.8), Inches(4.7)])

add_card(s, Inches(6.5), Inches(1.4), Inches(6.3), Inches(2.5),
    "Uitgebreid SDS (eSDS)", [
    "Verplicht bij ≥ 10 ton/jaar + gevaarlijk (of PBT/vPvB)",
    "Bevat blootstellingsscenario's (exposure scenarios)",
    "Operationele voorwaarden en risicobeheersmaatregelen",
    "DNEL/DMEL (mens) en PNEC (milieu) waarden",
    "Advies downstream gebruiker over risicobeheersing"
    ], INFO_BLUE)

add_card(s, Inches(6.5), Inches(4.2), Inches(6.3), Inches(2.5),
    "Wanneer is een SDS verplicht?", [
    "Stof/mengsel geclassificeerd als gevaarlijk (CLP)",
    "PBT- of vPvB-stof",
    "Stof op Kandidaatlijst (SVHC) in concentratie ≥ 0,1%",
    "Nieuw format: Verordening EU 2020/878",
    "Bijwerken bij nieuwe informatie of gewijzigde classificatie"
    ], SUCCESS_GREEN)

# ═══════════════════════════════════════════════════════
# SLIDE 14: DATA-DELING & CONSORTIUMS
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Data-deling & Consortiums")
add_footer(s, slide_num)

add_card(s, Inches(0.5), Inches(1.4), Inches(5.8), Inches(2.8),
    "SIEF — Substance Information Exchange Forum", [
    "Verplicht forum voor alle registranten dezelfde stof",
    "Doel: gegevens delen, dubbel werk voorkomen",
    "Dierproeven zoveel mogelijk delen/vermijden",
    "Opt-in of opt-out voor specifieke studies",
    "Vertrouwelijkheidsregime voor bedrijfsgevoelige data"
    ], DARK_BLUE)

add_card(s, Inches(6.8), Inches(1.4), Inches(5.8), Inches(2.8),
    "LoA — Letter of Access", [
    "Document waarmee een bedrijf toegang krijgt tot data",
    "Verkregen van lead registrant of consortium",
    "Bevat: toxicologische, ecotoxicologische data",
    "Kostenbesparing: data niet zelf genereren",
    "Essentieel voor bedrijven zonder eigen dataset"
    ], INFO_BLUE)

add_card(s, Inches(0.5), Inches(4.6), Inches(5.8), Inches(2.2),
    "Gezamenlijke indiening", [
    "Lead registrant dient gezamenlijk dossier in",
    "Co-registranten verwijzen naar lead dossier",
    "Besparing op testkosten en dossieropstelling",
    "Consortiumlidmaatschap: €15.000 — €40.000"
    ], SUCCESS_GREEN)

add_card(s, Inches(6.8), Inches(4.6), Inches(5.8), Inches(2.2),
    "Voordelen consortium", [
    "Kostenbesparing door data-deling",
    "Toegang tot bestaande toxicologische datasets",
    "Gezamenlijke chemische veiligheidsbeoordeling",
    "Expertise en ondersteuning bij indiening"
    ], WARN_ORANGE)

# ═══════════════════════════════════════════════════════
# SLIDE 15: SCIP DATABASE
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "SCIP Database")
add_footer(s, slide_num)

add_card(s, Inches(0.5), Inches(1.4), Inches(6.0), Inches(3.0),
    "Wat is SCIP?", [
    "Substances of Concern In articles as such or in complex objects (Products)",
    "EU-database met SVHC's in voorwerpen",
    "Beheerd door ECHA",
    "Doel: circulaire economie — stoffen van zorg traceerbaar",
    "Onderdeel van afvalbeleid: weten wat er in afval zit"
    ], DARK_BLUE)

add_card(s, Inches(6.8), Inches(1.4), Inches(6.0), Inches(3.0),
    "Wie moet melden?", [
    "Producenten van voorwerpen met SVHC > 0,1%",
    "Importeurs van voorwerpen met SVHC > 0,1%",
    "Assemblateurs van complexe objecten",
    "Leveranciers van voorwerpen (art. 33 verplichting)",
    "NIET: producenten/importeurs stoffen/mengsels"
    ], INFO_BLUE)

add_kpi_card(s, Inches(0.5), Inches(4.8), "SCIP", "Database naam", DARK_BLUE)
add_kpi_card(s, Inches(3.7), Inches(4.8), "> 0,1%", "SVHC drempelwaarde", CRIT_ORANGE)
add_kpi_card(s, Inches(6.9), Inches(4.8), "ECHA", "Beheerder", INFO_BLUE)
add_kpi_card(s, Inches(10.1), Inches(4.8), "2021", "Meldplicht ingegaan", SUCCESS_GREEN)

# ═══════════════════════════════════════════════════════
# SLIDE 16: UK REACH
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "UK REACH — Post-Brexit Verschillen")
add_footer(s, slide_num)

uk_data = [
    ["Aspect", "EU REACH", "UK REACH"],
    ["Bevoegde instantie", "ECHA (Helsinki)", "HSE (Health and Safety Executive)"],
    ["IT-systeem", "REACH-IT", "UK REACH IT"],
    ["Database", "ECHA-databases", "UK REACH substance database"],
    ["Registratie", "EU-registratie geldt in EU/EER", "UK-registratie nodig voor UK-markt"],
    ["CLP", "EU CLP (EG 1272/2008)", "UK CLP (gewijzigde versie)"],
    ["Kandidaatlijst", "EU Kandidaatlijst (240+ stoffen)", "UK Kandidaatlijst (overname EU-lijst)"],
]
add_table(s, Inches(0.5), Inches(1.4), Inches(12.3), uk_data,
    [Inches(2.5), Inches(4.9), Inches(4.9)])

add_callout(s, Inches(0.5), Inches(4.5), Inches(12.3),
    "⚠️ Voor de UK-markt is een aparte UK REACH-registratie vereist — EU-registratie geldt NIET in het VK")

add_card(s, Inches(0.5), Inches(5.5), Inches(12.3), Inches(1.3),
    "Praktische implicaties", [
    "Bedrijven die in zowel EU als VK leveren: dubbele registratie nodig",
    "UK REACH IT portaal: submit.ukreacht.com — Nederlandse helpdesk: chemischestoffengoedgeregeld.nl"
    ], DARK_BLUE)

# ═══════════════════════════════════════════════════════
# SLIDE 17: PHOENIX METALS CASE STUDY
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Phoenix Metals — Case Study", "Vanadium-elektrolyten uit staalslakken")
add_footer(s, slide_num)

add_card(s, Inches(0.5), Inches(1.4), Inches(5.8), Inches(2.5),
    "Over Phoenix Metals", [
    "Vervaardigt vanadium-elektrolyten uit staalslakken",
    "Toepassing: batterijopslag (VRFB — Vanadium Redox Flow)",
    "Locatie: IJmuiden (staalindustrie cluster)",
    "Pilot plant: huidige productie < 1 ton/jaar",
    "Opschaling: Demonstrator (1-10t) en Commercieel (>10t)"
    ], DARK_BLUE)

# Fasen tabel
fase_data = [
    ["Fase", "Periode", "Activiteiten", "Mijlpaal"],
    ["1", "Maand 1-2", "Stoffeninventarisatie, volumebepaling", "Inventarisatie compleet"],
    ["2", "Maand 3-6", "Data-verzameling, SIEF, LoA", "Dataset compleet"],
    ["3", "Maand 7-10", "CSR, blootstellingsscenario's", "CSR gereed"],
    ["4", "Maand 11-12", "IUCLID, indiening ECHA", "Dossier ingediend"],
    ["5", "Maand 13-15", "SDS-update, training, monitoring", "Volledig compliant"],
]
add_table(s, Inches(0.5), Inches(4.2), Inches(12.3), fase_data,
    [Inches(1.0), Inches(2.0), Inches(5.0), Inches(4.3)])

# Budget tabel rechtsboven
budget_data = [
    ["Post", "Bereik"],
    ["Externe toxicoloog/consultant", "€50.000 — €80.000"],
    ["Consortiumlidmaatschap", "€15.000 — €40.000"],
    ["ECHA-registratiebijdrage", "€10.000 — €30.000"],
    ["Aanvullende testen", "€20.000 — €100.000"],
    ["Interne kosten", "€25.000 — €40.000"],
    ["Totaal", "€120.000 — €290.000"],
]
add_table(s, Inches(6.8), Inches(1.4), Inches(5.8), budget_data,
    [Inches(3.5), Inches(2.3)])

# ═══════════════════════════════════════════════════════
# SLIDE 18: TONNAGE SCENARIO'S
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Tonnage Scenario's — Phoenix Metals")
add_footer(s, slide_num)

# Pilot
add_card(s, Inches(0.5), Inches(1.4), Inches(3.8), Inches(3.8),
    "Pilot Plant (< 1 ton/jaar)", [
    "Geen directe registratieplicht",
    "Downstream-gebruiker verplichtingen",
    "SDS opvolgen, RI&E, PBM, WIK-kaarten",
    "Kosten: minimaal (intern HSE)",
    "Risico: LAAG",
    "Aanbeveling: begin voorbereiding"
    ], SUCCESS_GREEN)

# Demonstrator
add_card(s, Inches(4.7), Inches(1.4), Inches(3.8), Inches(3.8),
    "Demonstrator (1-10 ton/jaar)", [
    "JA — registratieplicht",
    "Bijlage VII + aanvullend",
    "Geen CSR, wel safe use richtlijnen",
    "Kosten: €25.000 — €80.000 per stof",
    "Risico: GEMIDDELD",
    "Start 12 maanden vóór drempel"
    ], WARN_ORANGE)

# Commercieel
add_card(s, Inches(8.9), Inches(1.4), Inches(3.8), Inches(3.8),
    "Commercieel (> 10 ton/jaar)", [
    "JA — met volledige CSA en CSR",
    "Bijlage VII + VIII + IX (+ X bij ≥100t)",
    "CSR met blootstellingsscenario's + eSDS",
    "Kosten: €80.000 — €250.000+ per stof",
    "Risico: HOOG",
    "Consortium essentieel"
    ], CRIT_ORANGE)

# Scenario tabel
scen_data = [
    ["Scenario", "Phoenix Metals rol", "Verplichting"],
    ["Pilot (< 1 t/j)", "Downstream gebruiker", "SDS opvolgen, RI&E, PBM, WIK-kaarten"],
    ["Demonstrator (1-10 t/j)", "Registrant (vanadium)", "REACH-registratie + downstream hulpstoffen"],
    ["Commercieel (> 10 t/j)", "Registrant met CSA/CSR", "Volledige REACH + eSDS"],
]
add_table(s, Inches(0.5), Inches(5.6), Inches(12.3), scen_data,
    [Inches(2.5), Inches(3.5), Inches(6.3)])

# ═══════════════════════════════════════════════════════
# SLIDE 19: CHEMICALIËNREGISTER
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Chemicaliënregister — Phoenix Metals")
add_footer(s, slide_num)

chem_data = [
    ["#", "Chemische stof", "CAS-nummer", "ADR", "Volume", "SVHC", "REACH-status"],
    ["1", "Sodium hydroxide, 50%", "1310-73-2", "8", "100 l", "Nee", "Geregistreerd (leverancier)"],
    ["2", "Sulfuric acid, 75%", "7664-93-9", "8", "30 l", "Nee", "Geregistreerd (leverancier)"],
    ["3", "Sulfuric acid, 50%", "7664-93-9", "8", "70 l", "Nee", "Geregistreerd (leverancier)"],
    ["4", "Sulfuric acid, 25%", "7664-93-9", "8", "100 l", "Nee", "Geregistreerd (leverancier)"],
    ["5", "Aluminum sulfate 18H₂O", "7784-31-8", "N/A", "5 kg", "Nee", "Geregistreerd (leverancier)"],
    ["6", "Calcium oxide", "1305-78-8", "N/A", "10 kg", "Nee", "Geregistreerd (leverancier)"],
]
add_table(s, Inches(0.5), Inches(1.4), Inches(12.3), chem_data,
    [Inches(0.5), Inches(2.5), Inches(1.5), Inches(0.7), Inches(1.0), Inches(0.8), Inches(5.3)])

add_callout(s, Inches(0.5), Inches(4.5), Inches(12.3),
    "✅ Alle 6 chemicaliën zijn geregistreerd door leveranciers — Phoenix Metals heeft downstream-gebruikersverplichtingen")

add_card(s, Inches(0.5), Inches(5.5), Inches(12.3), Inches(1.3),
    "Downstream-gebruikersverplichtingen", [
    "SDS opvolgen en beschikbaar houden voor werknemers | RI&E TOX uitvoeren | PBM voorzien | WIK-kaarten up-to-date houden"
    ], DARK_BLUE)

# ═══════════════════════════════════════════════════════
# SLIDE 20: ACTUELE ONTWIKKELINGEN 2025
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Actuele Ontwikkelingen 2025")
add_footer(s, slide_num)

add_card(s, Inches(0.5), Inches(1.4), Inches(5.8), Inches(2.5),
    "CLP Updates", [
    "Nieuwe gevaarsklassen geïntroduceerd (2024-2025)",
    "Endocriene stoornissen: versterkte classificatie",
    "PFAS: specifieke classificatie-eisen",
    "Digitale etikettering pilot gestart",
    "Nanomaterialen: verfijnde criteria"
    ], INFO_BLUE)

add_card(s, Inches(6.8), Inches(1.4), Inches(5.8), Inches(2.5),
    "ECHA Enforcement", [
    "Verhoogde handhavingsactiviteiten",
    "Focus op downstream-gebruikers compliance",
    "SCIP database: steeds meer meldingen verwacht",
    "REACH compliance checks opgevoerd",
    "PFAS restrictievoorstellen in behandeling"
    ], CRIT_ORANGE)

add_card(s, Inches(0.5), Inches(4.2), Inches(5.8), Inches(2.5),
    "Sustainability & Circulair", [
    "Green Deal: chemicaliënbeleid versterkt",
    "CSS (Chemicals Strategy for Sustainability)",
    "Essential use concept geïntroduceerd",
    "Circulaire economie: nadruk op stofbeheersing",
    "Generic risk approach voor consumentenproducten"
    ], SUCCESS_GREEN)

add_card(s, Inches(6.8), Inches(4.2), Inches(5.8), Inches(2.5),
    "Belangrijke data", [
    "PFAS universele restrictie: verwachte beslissing 2025-2026",
    "CLP verordening update: implementatie 2025-2027",
    "Nieuwe Kandidaatlijst updates: 2x per jaar",
    "IUCLID 6 updates: continue",
    "REACH review: gepland evaluatie"
    ], WARN_ORANGE)

# ═══════════════════════════════════════════════════════
# SLIDE 21: KEY TAKEAWAYS
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
add_header_bar(s, "Key Takeaways")
add_footer(s, slide_num)

takeaways = [
    ("1", "REACH is de belangrijkste EU-verordening voor chemische stoffen — \"no data, no market\"", DARK_BLUE),
    ("2", "Registratieplicht geldt vanaf 1 ton/jaar — kosten stijgen exponentieel met tonnage", INFO_BLUE),
    ("3", "SVHC's (240+) vereisen extra communicatie, notificatie en mogelijk autorisatie", CRIT_ORANGE),
    ("4", "Phoenix Metals pilot (< 1t): geen registratieplicht, maar voorbereiding is essentieel", SUCCESS_GREEN),
    ("5", "Bij opschaling (≥ 1t): REACH-registratie nodig — budget €25.000 — €290.000 afhankelijk van scenario", WARN_ORANGE),
    ("6", "Alle 6 chemicaliën op het terrein zijn geregistreerd door leveranciers — downstream-verplichtingen gelden", DARK_BLUE),
    ("7", "Consortium-aansluiting bespaart kosten en tijd — start voorbereiding minimaal 12 maanden vóór drempel", INFO_BLUE),
]

for i, (num, text, color) in enumerate(takeaways):
    y = Inches(1.4) + Inches(0.8) * i
    # Number circle
    circ = s.shapes.add_shape(MSO_SHAPE.OVAL, Inches(0.7), y + Inches(0.05), Inches(0.5), Inches(0.5))
    circ.fill.solid()
    circ.fill.fore_color.rgb = color
    circ.line.fill.background()
    txb = s.shapes.add_textbox(Inches(0.7), y + Inches(0.1), Inches(0.5), Inches(0.4))
    txb.text_frame.paragraphs[0].text = num
    txb.text_frame.paragraphs[0].font.size = Pt(18)
    txb.text_frame.paragraphs[0].font.bold = True
    txb.text_frame.paragraphs[0].font.color.rgb = WHITE
    txb.text_frame.paragraphs[0].font.name = FONT
    txb.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
    # Text
    txb2 = s.shapes.add_textbox(Inches(1.5), y + Inches(0.08), Inches(11), Inches(0.55))
    txb2.text_frame.word_wrap = True
    txb2.text_frame.paragraphs[0].text = text
    txb2.text_frame.paragraphs[0].font.size = Pt(15)
    txb2.text_frame.paragraphs[0].font.color.rgb = TEXT_DARK
    txb2.text_frame.paragraphs[0].font.name = FONT

# ═══════════════════════════════════════════════════════
# SLIDE 22: VRAGEN & DISCUSSIE
# ═══════════════════════════════════════════════════════
slide_num += 1
s = prs.slides.add_slide(blank_layout)
# Full dark blue background
bg = s.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, SLIDE_W, SLIDE_H)
bg.fill.solid()
bg.fill.fore_color.rgb = DARK_BLUE
bg.line.fill.background()
# Logo
if os.path.exists(LOGO):
    s.shapes.add_picture(LOGO, SLIDE_W - Inches(2.0), Inches(0.5), Inches(1.5), Inches(1.35))

# Title
txBox = s.shapes.add_textbox(Inches(1), Inches(2.0), Inches(10), Inches(1.0))
tf = txBox.text_frame
p = tf.paragraphs[0]
p.text = "Vragen & Discussie"
p.font.size = Pt(40)
p.font.bold = True
p.font.color.rgb = WHITE
p.font.name = FONT

# Accent line
accent = s.shapes.add_shape(MSO_SHAPE.RECTANGLE, Inches(1), Inches(3.1), Inches(4), Inches(0.06))
accent.fill.solid()
accent.fill.fore_color.rgb = INFO_BLUE
accent.line.fill.background()

# Contact
txBox2 = s.shapes.add_textbox(Inches(1), Inches(3.5), Inches(10), Inches(2.0))
tf2 = txBox2.text_frame
tf2.word_wrap = True
p2 = tf2.paragraphs[0]
p2.text = "JvG Consultancy"
p2.font.size = Pt(22)
p2.font.bold = True
p2.font.color.rgb = WHITE
p2.font.name = FONT

p3 = tf2.add_paragraph()
p3.text = "Safety • Governance • Advisory"
p3.font.size = Pt(16)
p3.font.color.rgb = RGBColor(0xBB, 0xCC, 0xDD)
p3.font.name = FONT

p4 = tf2.add_paragraph()
p4.text = ""
p4.font.size = Pt(12)

p5 = tf2.add_paragraph()
p5.text = "ECHA — REACH: echa.europa.eu/regulations/reach"
p5.font.size = Pt(13)
p5.font.color.rgb = RGBColor(0x99, 0xAA, 0xBB)
p5.font.name = FONT

p6 = tf2.add_paragraph()
p6.text = "NL Helpdesk: chemischestoffengoedgeregeld.nl"
p6.font.size = Pt(13)
p6.font.color.rgb = RGBColor(0x99, 0xAA, 0xBB)
p6.font.name = FONT

p7 = tf2.add_paragraph()
p7.text = "Vanadium Consortium: vanadiumconsortium.com"
p7.font.size = Pt(13)
p7.font.color.rgb = RGBColor(0x99, 0xAA, 0xBB)
p7.font.name = FONT

# ─── SAVE ───
output_path = "/root/projects/jg/2026-consult-REACH-kennisdossier/deliverables/pptx/REACH_Presentatie_v1.0.pptx"
prs.save(output_path)
print(f"✅ Presentatie opgeslagen: {output_path}")
print(f"📊 Aantal slides: {slide_num}")
