Make a presentation of a air pollution pathogenesis for community medicine

Reading File
Reading File
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Running Command

mkdir -p /tmp/workspace/air-pollution-pptx && ls /tmp/workspace/air-pollution-pptx/

Writing File

~/air-pollution-pptx/build_pptx.py

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.util import Inches, Pt
import copy

# ─── COLOUR PALETTE ───────────────────────────────────────────────────────────
C_NAVY     = RGBColor(0x1A, 0x37, 0x5E)  # dark navy
C_TEAL     = RGBColor(0x00, 0x8B, 0x8B)  # dark teal
C_ORANGE   = RGBColor(0xE8, 0x6B, 0x1A)  # accent orange
C_LTBLUE   = RGBColor(0xD6, 0xE8, 0xF5)  # light blue fill
C_LTGRAY   = RGBColor(0xF2, 0xF4, 0xF7)  # light gray bg
C_WHITE    = RGBColor(0xFF, 0xFF, 0xFF)
C_DARK     = RGBColor(0x1E, 0x1E, 0x2E)  # near-black text
C_GREEN    = RGBColor(0x21, 0x7A, 0x3C)  # green
C_RED      = RGBColor(0xC0, 0x39, 0x2B)  # red

prs = Presentation()
prs.slide_width  = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]

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

def add_rect(slide, x, y, w, h, fill_rgb=None, line_rgb=None, line_width_pt=0):
    from pptx.util import Pt
    shape = slide.shapes.add_shape(
        1,  # MSO_SHAPE_TYPE.RECTANGLE
        Inches(x), Inches(y), Inches(w), Inches(h)
    )
    fill = shape.fill
    if fill_rgb:
        fill.solid()
        fill.fore_color.rgb = fill_rgb
    else:
        fill.background()
    line = shape.line
    if line_rgb:
        line.color.rgb = line_rgb
        line.width = Pt(line_width_pt)
    else:
        line.fill.background()
    return shape

def add_textbox(slide, x, y, w, h, text, fontsize=18, bold=False, color=C_DARK,
                align=PP_ALIGN.LEFT, wrap=True, italic=False, font_name="Calibri"):
    tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
    tf = tb.text_frame
    tf.word_wrap = wrap
    tf.margin_left = Pt(0)
    tf.margin_right = Pt(0)
    tf.margin_top = Pt(0)
    tf.margin_bottom = Pt(0)
    p = tf.paragraphs[0]
    p.alignment = align
    run = p.add_run()
    run.text = text
    run.font.name = font_name
    run.font.size = Pt(fontsize)
    run.font.bold = bold
    run.font.italic = italic
    run.font.color.rgb = color
    return tb

def add_bullet_textbox(slide, x, y, w, h, items, fontsize=14, title=None,
                       title_size=16, title_color=C_NAVY, bullet_color=C_DARK,
                       bg=None, padding=0.12, line_spacing=1.2):
    """Add a box with optional title and bullet list."""
    if bg:
        add_rect(slide, x, y, w, h, fill_rgb=bg)
    tb = slide.shapes.add_textbox(
        Inches(x + padding), Inches(y + padding),
        Inches(w - 2*padding), Inches(h - 2*padding)
    )
    tf = tb.text_frame
    tf.word_wrap = True
    tf.margin_left = Pt(2)
    tf.margin_right = Pt(2)
    tf.margin_top = Pt(2)
    tf.margin_bottom = Pt(2)
    first = True
    if title:
        p = tf.paragraphs[0] if first else tf.add_paragraph()
        first = False
        r = p.add_run()
        r.text = title
        r.font.name = "Calibri"
        r.font.bold = True
        r.font.size = Pt(title_size)
        r.font.color.rgb = title_color
        p.alignment = PP_ALIGN.LEFT
    for item in items:
        p = tf.paragraphs[0] if first else tf.add_paragraph()
        first = False
        p.alignment = PP_ALIGN.LEFT
        from pptx.oxml.ns import qn
        from lxml import etree
        pPr = p._pPr if p._pPr is not None else p._p.get_or_add_pPr()
        buChar = etree.SubElement(pPr, qn('a:buChar'))
        buChar.set('char', '●')
        r = p.add_run()
        r.text = "  " + item
        r.font.name = "Calibri"
        r.font.size = Pt(fontsize)
        r.font.color.rgb = bullet_color
    return tb


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 1 — TITLE SLIDE
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)

# Full-bleed navy background
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_NAVY)

# Teal accent bar left
add_rect(slide, 0, 0, 0.4, 7.5, fill_rgb=C_TEAL)

# Orange accent stripe
add_rect(slide, 0.4, 3.05, 12.933, 0.08, fill_rgb=C_ORANGE)

# Subtitle label
add_textbox(slide, 0.7, 1.2, 12, 0.7,
            "COMMUNITY MEDICINE SEMINAR SERIES",
            fontsize=14, bold=False, color=C_ORANGE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

# Main title
add_textbox(slide, 0.7, 1.9, 12, 1.5,
            "AIR POLLUTION:",
            fontsize=52, bold=True, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

add_textbox(slide, 0.7, 3.2, 12, 1.1,
            "Pathogenesis & Health Impact",
            fontsize=38, bold=False, color=C_LTBLUE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

# Divider line
add_rect(slide, 0.7, 4.45, 4.0, 0.04, fill_rgb=C_ORANGE)

# Tagline
add_textbox(slide, 0.7, 4.6, 12, 0.5,
            "Sources  ●  Pollutants  ●  Mechanisms  ●  Disease Burden  ●  Prevention",
            fontsize=13, bold=False, color=RGBColor(0xA8, 0xC4, 0xE0),
            align=PP_ALIGN.LEFT, font_name="Calibri")

add_textbox(slide, 0.7, 5.4, 12, 0.4,
            "Based on Park's Textbook of Preventive & Social Medicine | Murray & Nadel's Respiratory Medicine",
            fontsize=11, bold=False, color=RGBColor(0x80, 0xA0, 0xC0),
            align=PP_ALIGN.LEFT, font_name="Calibri")


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 2 — DEFINITION & OVERVIEW
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_TEAL)

add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
            "DEFINITION & OVERVIEW",
            fontsize=28, bold=True, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

# Definition box
add_rect(slide, 0.4, 1.3, 12.5, 1.5, fill_rgb=C_NAVY, line_rgb=C_TEAL, line_width_pt=1.5)
add_textbox(slide, 0.55, 1.35, 12.2, 1.4,
            "\"Air pollution signifies the presence in the ambient atmosphere of substances — gases, "
            "mixtures of gases and particulate matter — generated by human activities in concentrations "
            "that interfere with human health, safety or comfort, or injurious to vegetation, animals "
            "and other environmental media.\"",
            fontsize=13, bold=False, color=C_WHITE, italic=True,
            align=PP_ALIGN.LEFT, font_name="Calibri")

# 3 columns
cols = [
    ("Primary\nPollutants", "Emitted directly from sources: factory chimneys, exhaust pipes, wind-suspended dust", C_TEAL),
    ("Secondary\nPollutants", "Formed within the atmosphere via chemical reactions (e.g. Ozone from NOx + hydrocarbons in sunlight)", C_ORANGE),
    ("Particulate\nMatter (PM)", "Solid/liquid particles suspended in air. PM2.5 (<2.5 μm) most hazardous — penetrates deep alveoli", C_GREEN),
]
for i, (title, body, col) in enumerate(cols):
    xpos = 0.4 + i * 4.3
    add_rect(slide, xpos, 3.0, 4.1, 3.8, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=2)
    add_rect(slide, xpos, 3.0, 4.1, 0.55, fill_rgb=col)
    add_textbox(slide, xpos+0.1, 3.03, 3.9, 0.5, title,
                fontsize=14, bold=True, color=C_WHITE,
                align=PP_ALIGN.CENTER, font_name="Calibri")
    add_textbox(slide, xpos+0.15, 3.65, 3.8, 3.0, body,
                fontsize=13, bold=False, color=C_DARK,
                align=PP_ALIGN.LEFT, font_name="Calibri")

# Page number
add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "2", fontsize=10, color=C_TEAL, align=PP_ALIGN.RIGHT)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 3 — SOURCES OF AIR POLLUTION
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_ORANGE)

add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
            "SOURCES OF AIR POLLUTION",
            fontsize=28, bold=True, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

sources = [
    ("🚗  Automobiles", "Motor vehicles emit hydrocarbons, CO, lead, NOx & PM.\nDiesel engines produce black smoke & malodorous fumes.\nIn sunlight, NOx + hydrocarbons → photochemical smog (ozone)", C_ORANGE),
    ("🏭  Industries", "Combustion of fuel → smoke, SO₂, NOx, fly ash.\nPetrochemical: HF, HCl, organic halides.\nReleased from high chimneys at high temperature.", C_NAVY),
    ("🏠  Domestic", "Coal, wood, biomass burning → smoke, CO, SO₂.\nMajor source in developing countries / rural areas.\nCooking fires: indoor PM2.5 levels far exceed outdoor.", C_TEAL),
    ("🌱  Natural", "Volcanic eruptions, dust storms, forest fires, pollen.\nContribute to background PM & SO₂ levels.\nOften exacerbated by human land-use changes.", C_GREEN),
    ("☢️  Radioactive", "Radon gas from soil/rocks, nuclear facilities.\nBeta/gamma-emitting particles from fallout.\nIndoor accumulation in poorly ventilated buildings.", C_RED),
    ("🌾  Agricultural", "Ammonia from fertilizers & livestock → PM2.5.\nPesticide spraying releases VOCs.\nCrop residue burning — major seasonal PM spike.", RGBColor(0x80, 0x40, 0x10)),
]

for i, (title, body, col) in enumerate(sources):
    row, c = divmod(i, 3)
    xpos = 0.3 + c * 4.35
    ypos = 1.3 + row * 2.9
    add_rect(slide, xpos, ypos, 4.1, 2.6, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=2)
    add_rect(slide, xpos, ypos, 4.1, 0.5, fill_rgb=col)
    add_textbox(slide, xpos+0.1, ypos+0.04, 3.9, 0.45, title,
                fontsize=13, bold=True, color=C_WHITE,
                align=PP_ALIGN.LEFT, font_name="Calibri")
    add_textbox(slide, xpos+0.12, ypos+0.58, 3.85, 1.9, body,
                fontsize=11.5, bold=False, color=C_DARK,
                align=PP_ALIGN.LEFT, font_name="Calibri")

add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "3", fontsize=10, color=C_ORANGE, align=PP_ALIGN.RIGHT)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 4 — KEY POLLUTANTS
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_TEAL)

add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
            "KEY AIR POLLUTANTS & THEIR EFFECTS",
            fontsize=28, bold=True, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

pollutants = [
    ("SO₂\nSulphur Dioxide", "Combustion of fossil fuels.\nForms H₂SO₄ (acid rain).\nBronchospasm, mucus hypersecretion.", C_RED),
    ("NO₂\nNitrogen Dioxide", "Vehicle exhaust, power plants.\nPrecursor to ozone & smog.\nAirway inflammation, reduced lung function.", C_ORANGE),
    ("CO\nCarbon Monoxide", "Incomplete combustion.\nBinds Hb (COHb) — tissue hypoxia.\nCNS effects, cardiac ischaemia.", C_NAVY),
    ("O₃\nOzone", "Secondary pollutant from NOx + HC.\nOxidant — damages airway epithelium.\nExacerbates asthma/COPD.", C_TEAL),
    ("PM2.5\nFine Particles", "Deep alveolar deposition.\nSystemic inflammation, oxidative stress.\nCardiovascular & lung cancer risk.", C_RED),
    ("Pb  Lead", "Leaded petrol, paint, smelters.\nNeurotoxic — IQ loss in children.\nCritical route: air → food chain.", RGBColor(0x55, 0x00, 0x88)),
    ("Benzene\n& VOCs", "Petrol vapour, paints, solvents.\nCarcinogenic — leukaemia risk.\nMucous membrane irritants.", RGBColor(0x80, 0x40, 0x00)),
    ("Radon", "Soil/rock decay (U-238).\nIndoor accumulation in basements.\nLeading cause of lung cancer in non-smokers.", C_GREEN),
]

for i, (pollutant, detail, col) in enumerate(pollutants):
    row, c = divmod(i, 4)
    xpos = 0.25 + c * 3.26
    ypos = 1.28 + row * 2.88
    add_rect(slide, xpos, ypos, 3.1, 2.6, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=1.5)
    add_rect(slide, xpos, ypos, 3.1, 0.68, fill_rgb=col)
    add_textbox(slide, xpos+0.08, ypos+0.05, 2.95, 0.6, pollutant,
                fontsize=12, bold=True, color=C_WHITE,
                align=PP_ALIGN.LEFT, font_name="Calibri")
    add_textbox(slide, xpos+0.1, ypos+0.72, 2.9, 1.8, detail,
                fontsize=11, bold=False, color=C_DARK,
                align=PP_ALIGN.LEFT, font_name="Calibri")

add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "4", fontsize=10, color=C_TEAL, align=PP_ALIGN.RIGHT)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 5 — PATHOGENESIS (MECHANISTIC OVERVIEW)
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_RED)

add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
            "PATHOGENESIS — MECHANISTIC OVERVIEW",
            fontsize=28, bold=True, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

# Flow diagram — horizontal cascade
steps = [
    ("INHALATION\nEXPOSURE", "Gases, PM2.5,\nOzone, SO₂,\nNO₂", C_NAVY),
    ("DEPOSITION\nIN AIRWAY", "Upper tract:\nwater-soluble gases\nAlveoli: PM <2.5μm", C_TEAL),
    ("OXIDATIVE\nSTRESS", "ROS overwhelm\nantioxidant defenses\n(SOD, catalase, GSH)", C_ORANGE),
    ("INFLAMMATION", "NF-κB activation\nCytokines, chemokines\nNeutrophil influx", C_RED),
    ("TISSUE\nDAMAGE", "Epithelial injury\nAirway remodelling\nSystemic effects", RGBColor(0x7B, 0x00, 0x7B)),
]

box_w = 2.1
box_h = 3.2
arrow_w = 0.35
total_used = len(steps) * box_w + (len(steps)-1) * arrow_w
start_x = (13.333 - total_used) / 2

for i, (title, body, col) in enumerate(steps):
    xpos = start_x + i * (box_w + arrow_w)
    ypos = 1.7
    # Box
    add_rect(slide, xpos, ypos, box_w, box_h, fill_rgb=col)
    add_textbox(slide, xpos+0.08, ypos+0.12, box_w-0.16, 0.65, title,
                fontsize=12, bold=True, color=C_WHITE,
                align=PP_ALIGN.CENTER, font_name="Calibri")
    # Divider
    add_rect(slide, xpos+0.08, ypos+0.78, box_w-0.16, 0.04, fill_rgb=C_WHITE)
    add_textbox(slide, xpos+0.1, ypos+0.88, box_w-0.2, 2.15, body,
                fontsize=11, bold=False, color=C_WHITE,
                align=PP_ALIGN.LEFT, font_name="Calibri")
    # Arrow (not after last)
    if i < len(steps) - 1:
        ax = xpos + box_w + 0.02
        ay = ypos + box_h/2 - 0.1
        add_textbox(slide, ax, ay, arrow_w, 0.35,
                    "►", fontsize=22, bold=True, color=C_NAVY,
                    align=PP_ALIGN.CENTER, font_name="Calibri")

# Bottom note
add_rect(slide, 0.4, 5.1, 12.5, 1.9, fill_rgb=C_WHITE, line_rgb=C_NAVY, line_width_pt=1)
add_textbox(slide, 0.55, 5.18, 12.2, 1.75,
            "Phase 2 Response: When oxidant burden is great, excess ROS activate Nrf2 transcription factor → upregulates "
            "heme oxygenase-1, glutathione-S-transferase, catalase, superoxide dismutase & glutathione peroxidase. "
            "If Phase 2 fails → lipid peroxidation, protein oxidation, DNA damage → apoptosis. "
            "Proinflammatory cascades upregulate IL-6, IL-8, TNF-α, ICAM-1 → systemic vascular inflammation.",
            fontsize=11.5, bold=False, color=C_DARK,
            align=PP_ALIGN.LEFT, font_name="Calibri")

add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "5", fontsize=10, color=C_RED, align=PP_ALIGN.RIGHT)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 6 — RESPIRATORY PATHOGENESIS (detailed)
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_TEAL)

add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
            "RESPIRATORY PATHOGENESIS IN DETAIL",
            fontsize=28, bold=True, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

# Left column — Obstructive
add_rect(slide, 0.3, 1.25, 6.1, 5.95, fill_rgb=C_WHITE, line_rgb=C_TEAL, line_width_pt=2)
add_rect(slide, 0.3, 1.25, 6.1, 0.55, fill_rgb=C_TEAL)
add_textbox(slide, 0.4, 1.28, 5.9, 0.48, "OBSTRUCTIVE LUNG DISEASE (COPD / Asthma)",
            fontsize=13, bold=True, color=C_WHITE, align=PP_ALIGN.LEFT, font_name="Calibri")

copd_items = [
    "SO₂ & NO₂ → airway hyperresponsiveness & bronchoconstriction",
    "PM2.5 inhaled → alveolar macrophage activation → MMP release → elastin/collagen destruction (emphysema)",
    "Chronic neutrophilic/eosinophilic airway inflammation → mucus gland hypertrophy (chronic bronchitis)",
    "PM triggers mast cell degranulation → IgE-mediated asthma exacerbation",
    "Ozone (O₃): direct oxidant → ciliary damage → impaired mucociliary clearance → ↑ infection susceptibility",
    "Repeated exposure → airway wall remodelling, irreversible obstruction (↓ FEV₁/FVC)",
]
tb = slide.shapes.add_textbox(Inches(0.42), Inches(1.9), Inches(5.86), Inches(5.1))
tf = tb.text_frame
tf.word_wrap = True
from lxml import etree
from pptx.oxml.ns import qn
first = True
for item in copd_items:
    p = tf.paragraphs[0] if first else tf.add_paragraph()
    first = False
    pPr = p._p.get_or_add_pPr()
    buChar = etree.SubElement(pPr, qn('a:buChar'))
    buChar.set('char', '▸')
    r = p.add_run()
    r.text = "  " + item
    r.font.name = "Calibri"
    r.font.size = Pt(11.5)
    r.font.color.rgb = C_DARK

# Right column — Lung Cancer / Cardiovascular
add_rect(slide, 6.7, 1.25, 6.3, 2.95, fill_rgb=C_WHITE, line_rgb=C_RED, line_width_pt=2)
add_rect(slide, 6.7, 1.25, 6.3, 0.55, fill_rgb=C_RED)
add_textbox(slide, 6.82, 1.28, 6.06, 0.48, "LUNG CANCER",
            fontsize=13, bold=True, color=C_WHITE, align=PP_ALIGN.LEFT, font_name="Calibri")
lung_items = [
    "PAHs, benzene, nitrosamines → DNA adduct formation → oncogene activation (KRAS, EGFR mutations)",
    "Chronic oxidative stress → DNA strand breaks → TP53 mutations",
    "PM2.5 → epigenetic changes, global methylation shifts",
    "IARC Group 1 carcinogen: outdoor air pollution causes lung cancer",
]
tb2 = slide.shapes.add_textbox(Inches(6.82), Inches(1.9), Inches(6.06), Inches(2.1))
tf2 = tb2.text_frame
tf2.word_wrap = True
first = True
for item in lung_items:
    p = tf2.paragraphs[0] if first else tf2.add_paragraph()
    first = False
    pPr = p._p.get_or_add_pPr()
    buChar = etree.SubElement(pPr, qn('a:buChar'))
    buChar.set('char', '▸')
    r = p.add_run()
    r.text = "  " + item
    r.font.name = "Calibri"
    r.font.size = Pt(11.5)
    r.font.color.rgb = C_DARK

# Right bottom — Cardiovascular
add_rect(slide, 6.7, 4.38, 6.3, 2.82, fill_rgb=C_WHITE, line_rgb=C_ORANGE, line_width_pt=2)
add_rect(slide, 6.7, 4.38, 6.3, 0.55, fill_rgb=C_ORANGE)
add_textbox(slide, 6.82, 4.41, 6.06, 0.48, "CARDIOVASCULAR PATHOGENESIS",
            fontsize=13, bold=True, color=C_WHITE, align=PP_ALIGN.LEFT, font_name="Calibri")
cvd_items = [
    "PM2.5 enters systemic circulation → endothelial dysfunction, ↑CRP, fibrinogen",
    "Autonomic imbalance: ↑sympathetic tone → ↑HR, hypertension",
    "Accelerated atherosclerosis via oxidised LDL & foam cell formation",
    "Acute ischaemic events: plaque rupture & thrombosis triggered by PM2.5 peaks",
]
tb3 = slide.shapes.add_textbox(Inches(6.82), Inches(5.02), Inches(6.06), Inches(1.95))
tf3 = tb3.text_frame
tf3.word_wrap = True
first = True
for item in cvd_items:
    p = tf3.paragraphs[0] if first else tf3.add_paragraph()
    first = False
    pPr = p._p.get_or_add_pPr()
    buChar = etree.SubElement(pPr, qn('a:buChar'))
    buChar.set('char', '▸')
    r = p.add_run()
    r.text = "  " + item
    r.font.name = "Calibri"
    r.font.size = Pt(11.5)
    r.font.color.rgb = C_DARK

add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "6", fontsize=10, color=C_TEAL, align=PP_ALIGN.RIGHT)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 7 — HEALTH EFFECTS (DISEASE BURDEN)
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_GREEN)

add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
            "HEALTH EFFECTS & DISEASE BURDEN",
            fontsize=28, bold=True, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

# Stats boxes at top
stats = [
    ("7 million", "deaths/year\nattributable to air\npollution (WHO)", C_RED),
    ("PM2.5 ↑10μg/m³", "+~6% CVD mortality\n+~8% lung cancer\nrisk (meta-analyses)", C_ORANGE),
    ("15–20%", "higher mortality\nin high-pollution\ncities vs clean cities", C_NAVY),
    ("IARC 2013", "Declared outdoor air\npollution as Group 1\nHuman Carcinogen", C_TEAL),
]
for i, (val, label, col) in enumerate(stats):
    xpos = 0.3 + i * 3.2
    add_rect(slide, xpos, 1.28, 3.0, 1.8, fill_rgb=col)
    add_textbox(slide, xpos+0.1, 1.32, 2.8, 0.75, val,
                fontsize=24, bold=True, color=C_WHITE,
                align=PP_ALIGN.CENTER, font_name="Calibri")
    add_textbox(slide, xpos+0.1, 2.0, 2.8, 0.9, label,
                fontsize=11, bold=False, color=C_WHITE,
                align=PP_ALIGN.CENTER, font_name="Calibri")

# Effect categories
effects = [
    ("Respiratory", [
        "Asthma exacerbations",
        "COPD progression",
        "Chronic bronchitis",
        "Acute lower respiratory infections (children)",
        "Impaired lung development in children",
    ], C_TEAL),
    ("Cardiovascular", [
        "Ischaemic heart disease",
        "Stroke",
        "Arrhythmias / sudden cardiac death",
        "Hypertension",
        "Heart failure exacerbations",
    ], C_ORANGE),
    ("Systemic / Other", [
        "Lung & bladder cancer",
        "Adverse pregnancy outcomes (LBW, preterm)",
        "Neurotoxicity (lead: IQ loss in children)",
        "Type 2 diabetes mellitus",
        "Cognitive decline / dementia",
    ], C_NAVY),
]

for i, (category, items, col) in enumerate(effects):
    xpos = 0.3 + i * 4.35
    add_rect(slide, xpos, 3.25, 4.1, 3.95, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=2)
    add_rect(slide, xpos, 3.25, 4.1, 0.48, fill_rgb=col)
    add_textbox(slide, xpos+0.1, 3.28, 3.9, 0.42, category,
                fontsize=13, bold=True, color=C_WHITE,
                align=PP_ALIGN.LEFT, font_name="Calibri")
    tb = slide.shapes.add_textbox(Inches(xpos+0.12), Inches(3.82), Inches(3.86), Inches(3.25))
    tf = tb.text_frame
    tf.word_wrap = True
    first = True
    for item in items:
        p = tf.paragraphs[0] if first else tf.add_paragraph()
        first = False
        pPr = p._p.get_or_add_pPr()
        buChar = etree.SubElement(pPr, qn('a:buChar'))
        buChar.set('char', '●')
        r = p.add_run()
        r.text = "  " + item
        r.font.name = "Calibri"
        r.font.size = Pt(12)
        r.font.color.rgb = C_DARK

add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "7", fontsize=10, color=C_GREEN, align=PP_ALIGN.RIGHT)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 8 — INDOOR AIR POLLUTION
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_ORANGE)

add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
            "INDOOR AIR POLLUTION",
            fontsize=28, bold=True, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

# Intro banner
add_rect(slide, 0.3, 1.25, 12.7, 0.75, fill_rgb=C_NAVY, line_rgb=C_ORANGE, line_width_pt=1)
add_textbox(slide, 0.5, 1.3, 12.3, 0.65,
            "People spend >90% of time indoors. Indoor air often 2–5× more polluted than outdoor. "
            "Solid fuel combustion (biomass, coal) is the leading indoor pollution source globally.",
            fontsize=12, bold=False, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

# Left panel
add_rect(slide, 0.3, 2.18, 6.0, 5.05, fill_rgb=C_WHITE, line_rgb=C_TEAL, line_width_pt=1.5)
add_rect(slide, 0.3, 2.18, 6.0, 0.52, fill_rgb=C_TEAL)
add_textbox(slide, 0.42, 2.21, 5.76, 0.46, "INDOOR POLLUTANT SOURCES",
            fontsize=13, bold=True, color=C_WHITE, align=PP_ALIGN.LEFT, font_name="Calibri")

indoor_sources = [
    "Biomass/coal combustion: CO, PM2.5, PAHs, formaldehyde",
    "Tobacco smoke: >70 carcinogens incl. benzene, NNK, arsenic",
    "Radon: from soil/rocks, ↑ lung cancer risk (non-smokers)",
    "Building materials: formaldehyde (MDF), asbestos, VOCs from paints",
    "Mould/biological contaminants: triggers allergic inflammation",
    "Pesticides: organophosphates — respiratory & CNS toxicity",
    "Carbon monoxide from gas stoves/heaters: ↓ COHb oxygen-carrying capacity",
]
tb = slide.shapes.add_textbox(Inches(0.42), Inches(2.82), Inches(5.76), Inches(4.2))
tf = tb.text_frame; tf.word_wrap = True
first = True
for item in indoor_sources:
    p = tf.paragraphs[0] if first else tf.add_paragraph()
    first = False
    pPr = p._p.get_or_add_pPr()
    buChar = etree.SubElement(pPr, qn('a:buChar'))
    buChar.set('char', '▸')
    r = p.add_run()
    r.text = "  " + item
    r.font.name = "Calibri"
    r.font.size = Pt(11.5)
    r.font.color.rgb = C_DARK

# Right panel
add_rect(slide, 6.7, 2.18, 6.3, 5.05, fill_rgb=C_WHITE, line_rgb=C_RED, line_width_pt=1.5)
add_rect(slide, 6.7, 2.18, 6.3, 0.52, fill_rgb=C_RED)
add_textbox(slide, 6.82, 2.21, 6.06, 0.46, "HEALTH CONSEQUENCES",
            fontsize=13, bold=True, color=C_WHITE, align=PP_ALIGN.LEFT, font_name="Calibri")

indoor_health = [
    "Acute lower respiratory infections — leading cause of child mortality in LMICs",
    "COPD: indoor solid fuel use → 2–3× risk (women, non-smokers)",
    "Lung cancer: radon — attributable fraction ~10% of all lung cancer deaths",
    "Cardiovascular disease: CO & PM cause myocardial stress",
    "Adverse birth outcomes: LBW, stillbirth from chronic CO exposure",
    "Eye diseases: smoke irritation, corneal damage (biomass users)",
    "Musculoskeletal: carried firewood; burns from open fires",
]
tb2 = slide.shapes.add_textbox(Inches(6.82), Inches(2.82), Inches(6.06), Inches(4.2))
tf2 = tb2.text_frame; tf2.word_wrap = True
first = True
for item in indoor_health:
    p = tf2.paragraphs[0] if first else tf2.add_paragraph()
    first = False
    pPr = p._p.get_or_add_pPr()
    buChar = etree.SubElement(pPr, qn('a:buChar'))
    buChar.set('char', '▸')
    r = p.add_run()
    r.text = "  " + item
    r.font.name = "Calibri"
    r.font.size = Pt(11.5)
    r.font.color.rgb = C_DARK

add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "8", fontsize=10, color=C_ORANGE, align=PP_ALIGN.RIGHT)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 9 — WHO AQG & MEASUREMENT
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_TEAL)

add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
            "WHO AIR QUALITY GUIDELINES (AQG 2005/2021)",
            fontsize=28, bold=True, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

# Table header
add_rect(slide, 0.3, 1.25, 12.7, 0.55, fill_rgb=C_NAVY)
for col_info in [
    (0.3, 2.5, "POLLUTANT"),
    (2.8, 2.8, "AQG VALUE"),
    (5.6, 2.5, "AVERAGING TIME"),
    (8.1, 2.0, "BASIS FOR LIMIT"),
    (10.1, 2.9, "HEALTH CONCERN"),
]:
    x, w, label = col_info
    add_textbox(slide, x+0.1, 1.28, w-0.15, 0.46, label,
                fontsize=11, bold=True, color=C_WHITE,
                align=PP_ALIGN.LEFT, font_name="Calibri")

rows = [
    ("PM2.5", "10 μg/m³ (annual)\n25 μg/m³ (24-hr)", "Annual / 24-hr", "Cardiovascular & respiratory mortality — no safe threshold", C_LTGRAY),
    ("PM10", "20 μg/m³ (annual)\n50 μg/m³ (24-hr)", "Annual / 24-hr", "Respiratory hospital admissions, COPD exacerbations", C_WHITE),
    ("NO₂", "40 μg/m³ (annual)\n200 μg/m³ (1-hr)", "Annual / 1-hr", "Airway inflammation, ↑ asthma exacerbations", C_LTGRAY),
    ("SO₂", "500 μg/m³ (10-min)\n350 μg/m³ (1-hr)", "10-min / 1-hr", "Bronchoconstriction, especially in asthmatics", C_WHITE),
    ("Ozone", "100 μg/m³ (8-hr)\n150-200 μg/m³ (1-hr)", "8-hr / 1-hr", "Lung damage, reduced FEV₁, premature death", C_LTGRAY),
    ("CO", "10 mg/m³ (8-hr)\n100 mg/m³ (15-min)", "8-hr / 15-min", "Tissue hypoxia, cardiac ischaemia, neurotoxicity", C_WHITE),
    ("Lead", "0.5–1.0 μg/m³", "Annual", "Neurotoxicity (children), CVD, renal effects", C_LTGRAY),
]
row_h = 0.7
for i, (pollutant, value, time, basis, bg) in enumerate(rows):
    ypos = 1.8 + i * row_h
    add_rect(slide, 0.3, ypos, 12.7, row_h, fill_rgb=bg)
    add_textbox(slide, 0.4, ypos+0.06, 2.35, row_h-0.1, pollutant,
                fontsize=11, bold=True, color=C_NAVY,
                align=PP_ALIGN.LEFT, font_name="Calibri")
    add_textbox(slide, 2.9, ypos+0.04, 2.65, row_h-0.06, value,
                fontsize=10.5, bold=False, color=C_DARK,
                align=PP_ALIGN.LEFT, font_name="Calibri")
    add_textbox(slide, 5.65, ypos+0.06, 2.4, row_h-0.1, time,
                fontsize=10.5, bold=False, color=C_DARK,
                align=PP_ALIGN.LEFT, font_name="Calibri")
    add_textbox(slide, 8.15, ypos+0.04, 4.8, row_h-0.06, basis,
                fontsize=10, bold=False, color=C_DARK,
                align=PP_ALIGN.LEFT, font_name="Calibri")

# Border around table
add_rect(slide, 0.3, 1.25, 12.7, 1.8 + len(rows)*row_h - 1.25,
         fill_rgb=None, line_rgb=C_NAVY, line_width_pt=1.5)

add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "9", fontsize=10, color=C_TEAL, align=PP_ALIGN.RIGHT)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 10 — SCALE & TRANSPORT
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_GREEN)

add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
            "SPATIAL SCALE & TRANSPORT OF POLLUTANTS",
            fontsize=28, bold=True, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

scales = [
    ("LOCAL\n(Metres–Km)", "Household biomass burning\nRoad-side traffic\nAtmospheric lifetime: minutes–hours\nPollutants: PM, CO, NO₂, SO₂",
     "Poorly controlled neighbourhood\nsources; burning of biomass fuels\ncommon in developing countries.", C_RED),
    ("URBAN\n(City-wide)", "Vehicle exhaust, industry stacks\nAtmospheric lifetime: hours\nHigh conc. throughout city\nPollutants: NO, CO, VOCs",
     "Urban populations continuously\nexposed; hotspots near arterials,\nindustrial zones, waste-burning sites.", C_ORANGE),
    ("REGIONAL\n(100s–1000s km)", "Fine PM (<2.5μm) & ozone\nAtmospheric lifetime: days–weeks\nLong-range transport across borders\nAcid rain: SO₂ → H₂SO₄",
     "Ozone crosses national boundaries.\nWhitehorse Protocol covers SO₂\nand transboundary pollution.", C_TEAL),
    ("GLOBAL\n(Hemispheric)", "CO₂, N₂O, CH₄, CFCs\nAtmospheric lifetime: years–centuries\nGreenhouse warming effect\nOzone layer depletion",
     "Climate change amplifies pollution:\nheatwaves ↑ ozone; wildfires ↑ PM;\nlonger allergy seasons.", C_NAVY),
]
for i, (title, body1, body2, col) in enumerate(scales):
    xpos = 0.3 + i * 3.25
    add_rect(slide, xpos, 1.28, 3.0, 3.5, fill_rgb=col)
    add_textbox(slide, xpos+0.1, 1.32, 2.8, 0.7, title,
                fontsize=13, bold=True, color=C_WHITE,
                align=PP_ALIGN.CENTER, font_name="Calibri")
    add_rect(slide, xpos+0.08, 2.02, 2.84, 0.04, fill_rgb=C_WHITE)
    add_textbox(slide, xpos+0.1, 2.1, 2.8, 2.5, body1,
                fontsize=11, bold=False, color=C_WHITE,
                align=PP_ALIGN.LEFT, font_name="Calibri")
    add_rect(slide, xpos, 4.9, 3.0, 2.3, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=1.5)
    add_textbox(slide, xpos+0.1, 4.95, 2.8, 2.1, body2,
                fontsize=11, bold=False, color=C_DARK,
                align=PP_ALIGN.LEFT, font_name="Calibri")

add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "10", fontsize=10, color=C_GREEN, align=PP_ALIGN.RIGHT)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 11 — CONTROL MEASURES
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_GREEN)

add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
            "CONTROL MEASURES & PREVENTION",
            fontsize=28, bold=True, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

# 3 levels of intervention
interventions = [
    ("POLICY /\nLEGISLATIVE", [
        "Clean Air Acts — national ambient air quality standards (NAAQS)",
        "Vehicle emission norms (BS-VI / Euro 6)",
        "Mandatory EIA for new industries",
        "WHO AQG implementation & monitoring networks",
        "International: UNEP, WHO Global Action Plan on Air Pollution",
        "Phase-out of leaded petrol (achieved globally by 2021)",
    ], C_NAVY),
    ("TECHNICAL /\nENGINEERING", [
        "Catalytic converters, diesel particulate filters in vehicles",
        "Electrostatic precipitators & scrubbers in industry",
        "Tall stacks with dispersion modelling",
        "Transition to clean energy: solar, wind, hydro, nuclear",
        "Improved cook stoves / LPG substitution for biomass",
        "Green building design with ventilation & HEPA filtration",
    ], C_TEAL),
    ("COMMUNITY /\nINDIVIDUAL", [
        "Air Quality Index (AQI) dissemination & public alerts",
        "N95/P100 respirator use during pollution episodes",
        "Indoor plants & air purifiers (HEPA) for indoor protection",
        "Avoid outdoor exercise during high PM2.5/ozone days",
        "School health programs on clean cooking fuel adoption",
        "Avoid crop residue burning; promote composting",
    ], C_GREEN),
]

for i, (title, items, col) in enumerate(interventions):
    xpos = 0.3 + i * 4.35
    add_rect(slide, xpos, 1.28, 4.1, 5.95, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=2)
    add_rect(slide, xpos, 1.28, 4.1, 0.7, fill_rgb=col)
    add_textbox(slide, xpos+0.1, 1.3, 3.9, 0.66, title,
                fontsize=13, bold=True, color=C_WHITE,
                align=PP_ALIGN.CENTER, font_name="Calibri")
    tb = slide.shapes.add_textbox(Inches(xpos+0.15), Inches(2.08), Inches(3.8), Inches(5.0))
    tf = tb.text_frame; tf.word_wrap = True
    first = True
    for item in items:
        p = tf.paragraphs[0] if first else tf.add_paragraph()
        first = False
        pPr = p._p.get_or_add_pPr()
        buChar = etree.SubElement(pPr, qn('a:buChar'))
        buChar.set('char', '✓')
        r = p.add_run()
        r.text = "  " + item
        r.font.name = "Calibri"
        r.font.size = Pt(11.5)
        r.font.color.rgb = C_DARK

add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "11", fontsize=10, color=C_GREEN, align=PP_ALIGN.RIGHT)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 12 — VULNERABLE POPULATIONS
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_LTGRAY)
add_rect(slide, 0, 0, 13.333, 1.05, fill_rgb=C_NAVY)
add_rect(slide, 0, 1.05, 13.333, 0.07, fill_rgb=C_RED)

add_textbox(slide, 0.4, 0.15, 12.5, 0.8,
            "VULNERABLE POPULATIONS & EQUITY",
            fontsize=28, bold=True, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

groups = [
    ("👶 Children", [
        "Developing lungs — high ventilation/kg BW",
        "Impaired lung growth → ↓ peak lung function",
        "Lead: neurotoxicity, IQ loss, learning disabilities",
        "Acute RTI — major cause of child mortality",
    ], C_TEAL),
    ("🤰 Pregnant\nWomen", [
        "Transplacental transfer of CO, Pb, PAHs",
        "Low birth weight, preterm delivery, stillbirth",
        "Intrauterine growth restriction",
        "Placental oxidative stress & inflammation",
    ], C_ORANGE),
    ("👴 Elderly", [
        "Pre-existing COPD/CHD amplifies risk",
        "↓ antioxidant reserves & immune response",
        "PM2.5 → acute hospital admissions",
        "Higher case-fatality from pollution episodes",
    ], C_NAVY),
    ("💊 Pre-existing\nDisease", [
        "Asthmatics: SO₂, NO₂, O₃ trigger attacks",
        "COPD patients: PM exacerbates breathlessness",
        "IHD: PM2.5 → plaque destabilization, arrhythmia",
        "Diabetics: impaired detoxification pathways",
    ], C_RED),
    ("🏚 Socioeconomic\nDisadvantage", [
        "Reside near industrial/traffic zones",
        "Biomass cooking → constant indoor exposure",
        "No access to healthcare or clean alternatives",
        "Disproportionate burden in LMICs & slums",
    ], C_GREEN),
]

for i, (group, items, col) in enumerate(groups):
    row, c = divmod(i, 3)
    if i < 3:
        xpos = 0.3 + c * 4.35
        ypos = 1.28
    else:
        xpos = 1.6 + (i-3) * 4.35
        ypos = 4.48
    add_rect(slide, xpos, ypos, 4.1, 2.95, fill_rgb=C_WHITE, line_rgb=col, line_width_pt=2)
    add_rect(slide, xpos, ypos, 4.1, 0.55, fill_rgb=col)
    add_textbox(slide, xpos+0.1, ypos+0.06, 3.9, 0.46, group,
                fontsize=13, bold=True, color=C_WHITE,
                align=PP_ALIGN.LEFT, font_name="Calibri")
    tb = slide.shapes.add_textbox(Inches(xpos+0.12), Inches(ypos+0.65), Inches(3.86), Inches(2.2))
    tf = tb.text_frame; tf.word_wrap = True
    first = True
    for item in items:
        p = tf.paragraphs[0] if first else tf.add_paragraph()
        first = False
        pPr = p._p.get_or_add_pPr()
        buChar = etree.SubElement(pPr, qn('a:buChar'))
        buChar.set('char', '▸')
        r = p.add_run()
        r.text = "  " + item
        r.font.name = "Calibri"
        r.font.size = Pt(11)
        r.font.color.rgb = C_DARK

add_textbox(slide, 12.5, 7.15, 0.7, 0.3, "12", fontsize=10, color=C_RED, align=PP_ALIGN.RIGHT)


# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 13 — SUMMARY / KEY TAKEAWAYS
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_rgb=C_NAVY)
add_rect(slide, 0, 0, 0.4, 7.5, fill_rgb=C_TEAL)
add_rect(slide, 0.4, 1.1, 12.933, 0.07, fill_rgb=C_ORANGE)

add_textbox(slide, 0.7, 0.2, 12, 0.85,
            "KEY TAKEAWAYS",
            fontsize=32, bold=True, color=C_WHITE,
            align=PP_ALIGN.LEFT, font_name="Calibri")

takeaways = [
    ("1", "Air pollution is a global public health emergency — 7 million deaths/year; no safe lower threshold for PM2.5.", C_ORANGE),
    ("2", "Pathogenesis centres on ROS-driven oxidative stress → NF-κB activation → systemic inflammation → "
          "respiratory, cardiovascular and carcinogenic endpoints.", C_TEAL),
    ("3", "PM2.5 is the most hazardous fraction — penetrates alveoli, crosses into systemic circulation, "
          "triggers endothelial dysfunction and atherosclerosis.", C_GREEN),
    ("4", "Indoor air pollution (biomass combustion) causes acute RTIs in children and COPD/lung cancer in women — "
          "disproportionate burden in LMICs.", C_ORANGE),
    ("5", "Effective control requires multilevel intervention: legislation (AQG), engineering (clean energy, "
          "catalytic converters) and community education.", C_TEAL),
    ("6", "Vulnerable groups — children, pregnant women, elderly, low SES — require targeted protective policies "
          "and access to clean cooking fuel alternatives.", C_GREEN),
]

for i, (num, text, col) in enumerate(takeaways):
    ypos = 1.3 + i * 0.98
    add_rect(slide, 0.7, ypos, 0.52, 0.72, fill_rgb=col)
    add_textbox(slide, 0.72, ypos+0.1, 0.48, 0.55, num,
                fontsize=22, bold=True, color=C_DARK,
                align=PP_ALIGN.CENTER, font_name="Calibri")
    add_textbox(slide, 1.35, ypos+0.1, 11.6, 0.65, text,
                fontsize=13, bold=False, color=C_WHITE,
                align=PP_ALIGN.LEFT, font_name="Calibri")

# Reference line
add_textbox(slide, 0.7, 7.12, 12, 0.3,
            "Sources: Park's Textbook of Preventive & Social Medicine (24th ed.)  ●  Murray & Nadel's Textbook of Respiratory Medicine  "
            "●  WHO Air Quality Guidelines 2005/2021",
            fontsize=9.5, bold=False, color=RGBColor(0x80, 0xA0, 0xC0),
            align=PP_ALIGN.LEFT, font_name="Calibri")

# Save
out_path = "/tmp/workspace/air-pollution-pptx/Air_Pollution_Pathogenesis_Community_Medicine.pptx"
prs.save(out_path)
print(f"Saved: {out_path}")
Running Command

cd /tmp/workspace/air-pollution-pptx && python build_pptx.py 2>&1

Running Command

ls -lh /tmp/workspace/air-pollution-pptx/Air_Pollution_Pathogenesis_Community_Medicine.pptx

Your presentation is ready:

Air Pollution Pathogenesis Community Medicine

Presentation · PPTX


13 professionally designed slides built from Park's Textbook of Preventive & Social Medicine and Murray & Nadel's Respiratory Medicine:
SlideContent
1Title slide (navy/teal/orange theme)
2Definition & Overview — primary vs secondary pollutants, PM classification
3Sources of Air Pollution — automobiles, industries, domestic, natural, radioactive, agricultural
4Key Pollutants — SO₂, NO₂, CO, O₃, PM2.5, Lead, Benzene, Radon with mechanisms
5Pathogenesis — mechanistic flow diagram (Inhalation → Deposition → Oxidative Stress → Inflammation → Tissue Damage)
6Respiratory Pathogenesis in Detail — COPD/asthma, lung cancer, cardiovascular
7Health Effects & Disease Burden — WHO stats, disease categories
8Indoor Air Pollution — sources, health consequences (biomass, radon, CO, VOCs)
9WHO AQG Table — PM2.5, PM10, NO₂, SO₂, Ozone, CO, Lead guideline values
10Spatial Scale & Transport — local, urban, regional, global pollutant dynamics
11Control Measures — policy/legislative, technical/engineering, community/individual
12Vulnerable Populations & Equity — children, pregnant women, elderly, low SES
13Summary / Key Takeaways
The pathogenesis flow on Slide 5 highlights the core mechanism: oxidative stress from ROS overwhelming the Nrf2/Phase-2 antioxidant response → NF-κB-driven cytokine/chemokine release → airway inflammation, remodelling, and systemic vascular disease — directly sourced from Murray & Nadel's.
This is a shared conversation. Sign in to Orris to start your own chat.