attachment
attachment
attachment
attachment

Prepare notes pdf of this topic which includes a diagrams,flowcharts visual images and essay understanding exam oriented key points

I can see this is a pharmacy module covering ANS (Autonomic Nervous System) drugs and Autacoids - specifically Cholinergic/Anticholinergic drugs, Adrenergic/Antiadrenergic drugs, Serotonergic drugs, Histamine/Antihistaminics, and Migraine treatments.
Let me first read the medical library skill, then build comprehensive notes with diagrams and flowcharts.
Searching sources...
Reading File
analyse_media
analyse_media
Now I have a clear picture of all topics. Let me query the medical library for content and simultaneously read the PDF skill, then build the comprehensive notes PDF.
Finding Sources
Finding Sources
Finding Sources
Reading File
Good - the textbook DB didn't have exact matches. I have all the syllabus content from image analysis. Now I'll use a subagent to create the comprehensive PDF with diagrams, flowcharts, and visual notes.
Running Command

mkdir -p /home/daytona/workspace/ans-autacoids-notes && ls /home/daytona/workspace/ans-autacoids-notes/

Now let me write the comprehensive Python script to generate the full PDF:
Writing File

~/ans-autacoids-notes/generate_notes.py

#!/usr/bin/env python3
"""
ANS & Autacoids - Comprehensive Notes PDF Generator
Module 4.1: ANS AND AUTACOIDS (HomUG-Mod.Phar)
Topics: Cholinergic/Anticholinergic, Adrenergic/Antiadrenergic, 
        Serotonin/Autacoids, Histamine/Antihistaminic, Migraine
"""

from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.colors import (
    HexColor, white, black, red, blue, green, orange, purple,
    lightblue, lightyellow, lightgreen, Color
)
from reportlab.lib.units import cm, mm
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, KeepTogether, PageBreak
)
from reportlab.platypus.flowables import Flowable
from reportlab.graphics.shapes import (
    Drawing, Rect, String, Line, Polygon, Arrow, Circle, Ellipse,
    Group, Path
)
from reportlab.graphics import renderPDF
from reportlab.graphics.charts.barcharts import VerticalBarChart
import os

# ── Color Palette ──────────────────────────────────────────────────────────────
C_NAVY      = HexColor("#1A237E")
C_BLUE      = HexColor("#1565C0")
C_LIGHTBLUE = HexColor("#E3F2FD")
C_TEAL      = HexColor("#00695C")
C_TEAL_LT   = HexColor("#E0F2F1")
C_RED       = HexColor("#B71C1C")
C_RED_LT    = HexColor("#FFEBEE")
C_ORANGE    = HexColor("#E65100")
C_ORANGE_LT = HexColor("#FFF3E0")
C_PURPLE    = HexColor("#4A148C")
C_PURPLE_LT = HexColor("#F3E5F5")
C_GREEN     = HexColor("#1B5E20")
C_GREEN_LT  = HexColor("#E8F5E9")
C_YELLOW    = HexColor("#F57F17")
C_YELLOW_LT = HexColor("#FFFDE7")
C_GREY      = HexColor("#424242")
C_GREY_LT   = HexColor("#F5F5F5")
C_WHITE     = white

W, H = A4  # 595 x 842

# ── Styles ─────────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

def make_style(name, parent="Normal", **kw):
    s = ParagraphStyle(name, parent=styles[parent], **kw)
    return s

TITLE_STYLE = make_style("TitlePage", fontSize=28, textColor=C_WHITE,
                         alignment=TA_CENTER, spaceAfter=8, fontName="Helvetica-Bold")
SUBTITLE_STYLE = make_style("SubtitlePage", fontSize=14, textColor=C_LIGHTBLUE,
                            alignment=TA_CENTER, spaceAfter=4, fontName="Helvetica")
H1 = make_style("H1", fontSize=17, textColor=C_WHITE, fontName="Helvetica-Bold",
                spaceAfter=6, spaceBefore=2, alignment=TA_CENTER)
H2 = make_style("H2", fontSize=13, textColor=C_NAVY, fontName="Helvetica-Bold",
                spaceAfter=4, spaceBefore=8)
H3 = make_style("H3", fontSize=11, textColor=C_BLUE, fontName="Helvetica-Bold",
                spaceAfter=3, spaceBefore=5)
BODY = make_style("Body", fontSize=9.5, textColor=C_GREY, spaceAfter=3,
                  leading=14, fontName="Helvetica")
BODY_BOLD = make_style("BodyBold", fontSize=9.5, textColor=black, fontName="Helvetica-Bold",
                       spaceAfter=2, leading=13)
SMALL = make_style("Small", fontSize=8.5, textColor=C_GREY, spaceAfter=2, leading=12)
EXAM_TIP = make_style("ExamTip", fontSize=9, textColor=C_RED, fontName="Helvetica-Bold",
                      spaceAfter=2, leading=13, leftIndent=6)
KEY_POINT = make_style("KeyPoint", fontSize=9.5, textColor=C_TEAL, fontName="Helvetica-BoldOblique",
                       spaceAfter=2, leading=13)
BULLET = make_style("Bullet", fontSize=9.5, textColor=C_GREY, spaceAfter=2, leading=13,
                    leftIndent=12, bulletIndent=4, fontName="Helvetica")
TABLE_HDR = make_style("TableHdr", fontSize=9, textColor=C_WHITE, fontName="Helvetica-Bold",
                       alignment=TA_CENTER)
TABLE_CELL = make_style("TableCell", fontSize=8.5, textColor=C_GREY, fontName="Helvetica",
                        alignment=TA_LEFT)
TABLE_CELL_C = make_style("TableCellC", fontSize=8.5, textColor=C_GREY, fontName="Helvetica",
                           alignment=TA_CENTER)
CENTER = make_style("Center", fontSize=9.5, textColor=C_GREY, alignment=TA_CENTER)

# ── Helper flowables ───────────────────────────────────────────────────────────
def sp(h=6): return Spacer(1, h)
def hr(color=C_BLUE, thickness=1): return HRFlowable(width="100%", thickness=thickness, color=color)

class ColorBox(Flowable):
    """Colored background rectangle with centered text."""
    def __init__(self, text, bg_color, text_color=C_WHITE, width=None, height=28, font="Helvetica-Bold", font_size=13):
        super().__init__()
        self.text = text
        self.bg_color = bg_color
        self.text_color = text_color
        self._width = width
        self._height = height
        self.font = font
        self.font_size = font_size

    def wrap(self, aw, ah):
        self.width = self._width or aw
        self.height = self._height
        return self.width, self.height

    def draw(self):
        c = self.canv
        c.setFillColor(self.bg_color)
        c.roundRect(0, 0, self.width, self.height, 6, fill=1, stroke=0)
        c.setFillColor(self.text_color)
        c.setFont(self.font, self.font_size)
        c.drawCentredString(self.width / 2, self.height / 2 - self.font_size / 3, self.text)

class SectionHeader(Flowable):
    """Gradient-like section header bar."""
    def __init__(self, text, bg=C_NAVY, sub="", icon=""):
        super().__init__()
        self.text = text
        self.bg = bg
        self.sub = sub
        self.icon = icon

    def wrap(self, aw, ah):
        self.width = aw
        self.height = 36 if not self.sub else 52
        return self.width, self.height

    def draw(self):
        c = self.canv
        c.setFillColor(self.bg)
        c.roundRect(0, 0, self.width, self.height, 8, fill=1, stroke=0)
        # Accent stripe
        c.setFillColor(HexColor("#FFFFFF30"))
        c.roundRect(self.width - 80, 4, 76, self.height - 8, 4, fill=1, stroke=0)
        c.setFillColor(C_WHITE)
        c.setFont("Helvetica-Bold", 14)
        y = self.height / 2 + (8 if self.sub else 0) - 5
        label = (self.icon + " " if self.icon else "") + self.text
        c.drawString(14, y, label)
        if self.sub:
            c.setFont("Helvetica", 9)
            c.setFillColor(HexColor("#BBDEFB"))
            c.drawString(14, y - 16, self.sub)


class DiagramFlowchart(Flowable):
    """Renders a vertical flowchart from a list of (text, color) tuples."""
    def __init__(self, steps, width=480, arrow=True):
        super().__init__()
        self.steps = steps
        self._w = width
        self.arrow = arrow
        self.box_h = 34
        self.gap = 18
        total = len(steps) * (self.box_h + self.gap) - self.gap
        self._h = total + 10

    def wrap(self, aw, ah):
        self.width = min(self._w, aw)
        return self.width, self._h

    def draw(self):
        c = self.canv
        bh = self.box_h
        gap = self.gap
        bw = self.width - 30
        x0 = 15
        y = self._h - bh - 5

        for i, (text, color) in enumerate(self.steps):
            # Box
            c.setFillColor(color)
            c.roundRect(x0, y, bw, bh, 7, fill=1, stroke=0)
            # Text
            c.setFillColor(C_WHITE)
            c.setFont("Helvetica-Bold", 9)
            # Wrap long text
            lines = []
            words = text.split()
            line = ""
            for w in words:
                test = (line + " " + w).strip()
                if c.stringWidth(test, "Helvetica-Bold", 9) < bw - 16:
                    line = test
                else:
                    lines.append(line)
                    line = w
            if line:
                lines.append(line)
            total_text_h = len(lines) * 12
            ty = y + bh / 2 + total_text_h / 2 - 10
            for ln in lines:
                c.drawCentredString(x0 + bw / 2, ty, ln)
                ty -= 12
            # Arrow
            if self.arrow and i < len(self.steps) - 1:
                ax = x0 + bw / 2
                ay_top = y - 2
                ay_bot = y - gap + 2
                c.setStrokeColor(C_GREY)
                c.setFillColor(C_GREY)
                c.setLineWidth(1.5)
                c.line(ax, ay_top, ax, ay_bot + 6)
                # Arrowhead
                c.setLineWidth(0)
                p = c.beginPath()
                p.moveTo(ax, ay_bot)
                p.lineTo(ax - 5, ay_bot + 8)
                p.lineTo(ax + 5, ay_bot + 8)
                p.close()
                c.drawPath(p, fill=1, stroke=0)
            y -= bh + gap


class ANSNervesDiagram(Flowable):
    """Custom ANS division diagram."""
    def __init__(self, width=500):
        super().__init__()
        self._w = width
        self._h = 200

    def wrap(self, aw, ah):
        self.width = min(self._w, aw)
        self.height = self._h
        return self.width, self.height

    def draw(self):
        c = self.canv
        w = self.width
        h = self.height

        # CNS box
        c.setFillColor(C_NAVY)
        c.roundRect(w/2 - 70, h - 45, 140, 38, 6, fill=1, stroke=0)
        c.setFillColor(C_WHITE)
        c.setFont("Helvetica-Bold", 10)
        c.drawCentredString(w/2, h - 22, "CNS (Brain & Spinal Cord)")

        # Left branch: Parasympathetic
        c.setFillColor(C_TEAL)
        c.roundRect(20, h/2 - 15, 130, 32, 6, fill=1, stroke=0)
        c.setFillColor(C_WHITE)
        c.setFont("Helvetica-Bold", 9)
        c.drawCentredString(85, h/2 + 2, "PARASYMPATHETIC")
        c.setFont("Helvetica", 7.5)
        c.drawCentredString(85, h/2 - 9, "(Craniosacral)")

        # Right branch: Sympathetic
        c.setFillColor(C_RED)
        c.roundRect(w - 150, h/2 - 15, 130, 32, 6, fill=1, stroke=0)
        c.setFillColor(C_WHITE)
        c.setFont("Helvetica-Bold", 9)
        c.drawCentredString(w - 85, h/2 + 2, "SYMPATHETIC")
        c.setFont("Helvetica", 7.5)
        c.drawCentredString(w - 85, h/2 - 9, "(Thoracolumbar)")

        # Lines from CNS
        c.setStrokeColor(C_TEAL)
        c.setLineWidth(2)
        c.line(w/2 - 50, h - 45, 150, h/2 + 17)
        c.setStrokeColor(C_RED)
        c.line(w/2 + 50, h - 45, w - 150, h/2 + 17)

        # NT labels: Para -> ACh
        c.setFillColor(C_TEAL_LT)
        c.roundRect(15, 30, 140, 52, 5, fill=1, stroke=0)
        c.setFillColor(C_TEAL)
        c.setFont("Helvetica-Bold", 8.5)
        c.drawCentredString(85, 65, "Neurotransmitter:")
        c.setFont("Helvetica", 8.5)
        c.drawCentredString(85, 53, "Acetylcholine (ACh)")
        c.setFont("Helvetica-Bold", 8)
        c.setFillColor(C_TEAL)
        c.drawCentredString(85, 40, "Receptors: M1-M5 / N")

        # NT labels: Sym -> NE/Epi
        c.setFillColor(C_RED_LT)
        c.roundRect(w - 155, 30, 140, 52, 5, fill=1, stroke=0)
        c.setFillColor(C_RED)
        c.setFont("Helvetica-Bold", 8.5)
        c.drawCentredString(w - 85, 65, "Neurotransmitter:")
        c.setFont("Helvetica", 8.5)
        c.drawCentredString(w - 85, 53, "NE / Epinephrine")
        c.setFont("Helvetica-Bold", 8)
        c.drawCentredString(w - 85, 40, "Receptors: α1,α2 / β1,β2,β3")

        # Lines to NT boxes
        c.setStrokeColor(C_TEAL)
        c.setLineWidth(1.5)
        c.line(85, h/2 - 15, 85, 82)
        c.setStrokeColor(C_RED)
        c.line(w - 85, h/2 - 15, w - 85, 82)

        # "REST & DIGEST" vs "FIGHT OR FLIGHT"
        c.setFont("Helvetica-BoldOblique", 8)
        c.setFillColor(C_TEAL)
        c.drawCentredString(85, 20, '"Rest & Digest"')
        c.setFillColor(C_RED)
        c.drawCentredString(w - 85, 20, '"Fight or Flight"')


class ReceptorDiagram(Flowable):
    """Adrenergic receptors summary diagram."""
    def __init__(self, width=500):
        super().__init__()
        self._w = width
        self._h = 190

    def wrap(self, aw, ah):
        self.width = min(self._w, aw)
        self.height = self._h
        return self.width, self.height

    def draw(self):
        c = self.canv
        w = self.width

        # Title
        c.setFillColor(C_NAVY)
        c.roundRect(0, 165, w, 22, 4, fill=1, stroke=0)
        c.setFillColor(C_WHITE)
        c.setFont("Helvetica-Bold", 10)
        c.drawCentredString(w/2, 171, "ADRENERGIC RECEPTORS - Overview")

        # Alpha receptors
        items = [
            ("α1", "Vasoconstriction\nMydriasis\nUrinary retention", C_RED, 5),
            ("α2", "Presynaptic inhibition\nDecreased NE release", HexColor("#C62828"), 130),
            ("β1", "↑HR, ↑Contractility\nRenin release\n(Heart & Kidney)", C_BLUE, 255),
            ("β2", "Bronchodilation\nVasodilation\nUterine relaxation", HexColor("#1565C0"), 380),
        ]
        for label, desc, col, xpos in items:
            bw = 110
            c.setFillColor(col)
            c.roundRect(xpos, 95, bw, 32, 5, fill=1, stroke=0)
            c.setFillColor(C_WHITE)
            c.setFont("Helvetica-Bold", 13)
            c.drawCentredString(xpos + bw/2, 110, label)

            c.setFillColor(HexColor("#F5F5F5"))
            c.roundRect(xpos, 5, bw, 86, 4, fill=1, stroke=0)
            c.setFillColor(C_GREY)
            c.setFont("Helvetica", 7.5)
            lines = desc.split("\n")
            ty = 75
            for ln in lines:
                c.drawCentredString(xpos + bw/2, ty, ln)
                ty -= 13

            # connect line
            c.setStrokeColor(col)
            c.setLineWidth(1.5)
            c.line(xpos + bw/2, 95, xpos + bw/2, 91)


class SerotoninPathway(Flowable):
    """Serotonin synthesis and action diagram."""
    def __init__(self, width=500):
        super().__init__()
        self._w = width
        self._h = 160

    def wrap(self, aw, ah):
        self.width = min(self._w, aw)
        self.height = self._h
        return self.width, self.height

    def draw(self):
        c = self.canv
        w = self.width

        steps = [
            ("Tryptophan\n(Diet)", w*0.1, 100),
            ("5-HTP", w*0.3, 100),
            ("Serotonin (5-HT)", w*0.55, 100),
            ("Releases into\nSynapse", w*0.8, 100),
        ]
        colors = [C_GREEN, C_TEAL, C_PURPLE, C_BLUE]
        for i, ((label, x, y), col) in enumerate(zip(steps, colors)):
            bw, bh = 95, 38
            c.setFillColor(col)
            c.roundRect(x - bw/2, y - bh/2, bw, bh, 6, fill=1, stroke=0)
            c.setFillColor(C_WHITE)
            c.setFont("Helvetica-Bold", 8)
            lns = label.split("\n")
            ty = y + (len(lns)-1)*6
            for ln in lns:
                c.drawCentredString(x, ty, ln)
                ty -= 12
            # arrow
            if i < len(steps) - 1:
                nx = steps[i+1][1]
                ax1 = x + bw/2 + 2
                ax2 = nx - bw/2 - 2
                mid_y = y
                c.setStrokeColor(C_GREY)
                c.setFillColor(C_GREY)
                c.setLineWidth(1.5)
                c.line(ax1, mid_y, ax2, mid_y)
                p = c.beginPath()
                p.moveTo(ax2, mid_y)
                p.lineTo(ax2 - 7, mid_y + 4)
                p.lineTo(ax2 - 7, mid_y - 4)
                p.close()
                c.drawPath(p, fill=1, stroke=0)
            # enzyme label
            if i == 0:
                c.setFillColor(C_ORANGE)
                c.setFont("Helvetica-Oblique", 7.5)
                mid = (x + steps[1][1])/2
                c.drawCentredString(mid + 5, y + 26, "Tryptophan")
                c.drawCentredString(mid + 5, y + 16, "Hydroxylase")
            elif i == 1:
                c.setFillColor(C_ORANGE)
                c.setFont("Helvetica-Oblique", 7.5)
                mid = (x + steps[2][1])/2
                c.drawCentredString(mid, y + 26, "AADC")
                c.drawCentredString(mid, y + 16, "(Decarboxylase)")

        # Reuptake transporter
        c.setFillColor(C_RED_LT)
        c.roundRect(w*0.55 - 55, 20, 110, 50, 5, fill=1, stroke=0)
        c.setFillColor(C_RED)
        c.setFont("Helvetica-Bold", 8)
        c.drawCentredString(w*0.55, 55, "SERT (Reuptake)")
        c.setFont("Helvetica", 7.5)
        c.drawCentredString(w*0.55, 43, "Blocked by SSRIs/SNRIs")
        c.drawCentredString(w*0.55, 31, "→ ↑ synaptic 5-HT")

        # Arrow from synapse down to SERT
        c.setStrokeColor(C_RED)
        c.setLineWidth(1.2)
        c.line(w*0.55, 70, w*0.55, 79)


class MigrainePathway(Flowable):
    """Migraine pathophysiology flowchart."""
    def __init__(self, width=480):
        super().__init__()
        self._w = width
        self._h = 200

    def wrap(self, aw, ah):
        self.width = min(self._w, aw)
        self.height = self._h
        return self.width, self.height

    def draw(self):
        c = self.canv
        w = self.width

        boxes = [
            ("Trigger\n(Stress/Hormones/Food)", C_ORANGE, w/2, 183),
            ("Cortical Spreading\nDepression (CSD)", C_RED, w/2, 143),
            ("Trigeminal Nerve\nActivation", C_PURPLE, w/2, 103),
            ("CGRP + Substance P\nRelease", C_BLUE, w/2, 63),
            ("Neurogenic\nInflammation + PAIN", C_RED, w/2, 23),
        ]
        bw, bh = 180, 30
        for i, (label, col, x, y) in enumerate(boxes):
            c.setFillColor(col)
            c.roundRect(x - bw/2, y, bw, bh, 6, fill=1, stroke=0)
            c.setFillColor(C_WHITE)
            c.setFont("Helvetica-Bold", 8)
            lns = label.split("\n")
            ty = y + bh/2 + (len(lns)-1)*5
            for ln in lns:
                c.drawCentredString(x, ty, ln)
                ty -= 11
            if i < len(boxes) - 1:
                ny = boxes[i+1][3] + bh
                c.setStrokeColor(C_GREY)
                c.setFillColor(C_GREY)
                c.setLineWidth(1.5)
                c.line(x, y, x, ny + 2)
                p = c.beginPath()
                p.moveTo(x, ny + 2)
                p.lineTo(x - 5, ny + 10)
                p.lineTo(x + 5, ny + 10)
                p.close()
                c.drawPath(p, fill=1, stroke=0)

        # Treatment annotation on right
        c.setFillColor(C_GREEN_LT)
        c.roundRect(w*0.62, 55, 130, 40, 5, fill=1, stroke=0)
        c.setFillColor(C_GREEN)
        c.setFont("Helvetica-Bold", 8)
        c.drawCentredString(w*0.62 + 65, 84, "CGRP Antagonists:")
        c.setFont("Helvetica", 7.5)
        c.drawCentredString(w*0.62 + 65, 73, "Erenumab, Rimegepant")
        c.drawCentredString(w*0.62 + 65, 62, "Triptans (5-HT1 agonists)")
        c.setStrokeColor(C_GREEN)
        c.setLineWidth(1)
        c.line(w/2 + bw/2, 78, w*0.62, 78)


# ── Build Document ─────────────────────────────────────────────────────────────
def build_pdf(output_path):
    doc = SimpleDocTemplate(
        output_path,
        pagesize=A4,
        rightMargin=1.8*cm, leftMargin=1.8*cm,
        topMargin=1.8*cm, bottomMargin=1.8*cm,
        title="ANS & Autacoids - Module 4.1 Notes",
        author="PharmNotes",
    )

    story = []

    # ══════════════════════════════════════════════════════════════
    # COVER PAGE
    # ══════════════════════════════════════════════════════════════
    class CoverPage(Flowable):
        def wrap(self, aw, ah):
            self.width = aw
            self.height = ah
            return aw, ah

        def draw(self):
            c = self.canv
            w, h = W - 3.6*cm, H - 3.6*cm
            # Background gradient bands
            bands = [
                (C_NAVY, h),
                (HexColor("#1A3A6E"), h*0.7),
                (HexColor("#1B4F8A"), h*0.4),
            ]
            c.setFillColor(C_NAVY)
            c.rect(0, 0, w, h, fill=1, stroke=0)
            # Top accent
            c.setFillColor(C_BLUE)
            c.roundRect(0, h - 10, w, 10, 0, fill=1, stroke=0)
            c.setFillColor(C_ORANGE)
            c.roundRect(0, h - 18, w, 8, 0, fill=1, stroke=0)

            # Module badge
            c.setFillColor(C_ORANGE)
            c.roundRect(w/2 - 90, h*0.78, 180, 34, 8, fill=1, stroke=0)
            c.setFillColor(C_WHITE)
            c.setFont("Helvetica-Bold", 11)
            c.drawCentredString(w/2, h*0.78 + 20, "MODULE 4.1 | HomUG-Mod.Phar")
            c.setFont("Helvetica", 9)
            c.drawCentredString(w/2, h*0.78 + 8, "Pharmacology Notes")

            # Main title
            c.setFillColor(C_WHITE)
            c.setFont("Helvetica-Bold", 30)
            c.drawCentredString(w/2, h*0.62, "ANS & AUTACOIDS")
            c.setFillColor(HexColor("#BBDEFB"))
            c.setFont("Helvetica", 14)
            c.drawCentredString(w/2, h*0.54, "Autonomic Nervous System Drugs")

            # Divider
            c.setStrokeColor(C_ORANGE)
            c.setLineWidth(2)
            c.line(w/2 - 120, h*0.51, w/2 + 120, h*0.51)

            # Topic chips
            topics = [
                ("Cholinergic", C_TEAL, 50, h*0.44),
                ("Anticholinergic", HexColor("#00897B"), 160, h*0.44),
                ("Adrenergic", C_RED, 285, h*0.44),
                ("Antiadrenergic", HexColor("#C62828"), 405, h*0.44),
                ("Serotonin", C_PURPLE, 90, h*0.36),
                ("Histamine", C_ORANGE, 210, h*0.36),
                ("Migraine", HexColor("#880E4F"), 330, h*0.36),
                ("Autacoids", HexColor("#1A237E"), 450, h*0.36),
            ]
            for label, col, x, y in topics:
                tw = c.stringWidth(label, "Helvetica-Bold", 8.5) + 14
                c.setFillColor(col)
                c.roundRect(x, y, tw, 18, 5, fill=1, stroke=0)
                c.setFillColor(C_WHITE)
                c.setFont("Helvetica-Bold", 8.5)
                c.drawCentredString(x + tw/2, y + 5, label)

            # Bottom info
            c.setFillColor(HexColor("#1565C0"))
            c.roundRect(0, 0, w, 60, 0, fill=1, stroke=0)
            c.setFillColor(C_WHITE)
            c.setFont("Helvetica-Bold", 10)
            c.drawCentredString(w/2, 42, "Exam-Oriented Study Notes")
            c.setFont("Helvetica", 8.5)
            c.setFillColor(HexColor("#BBDEFB"))
            c.drawCentredString(w/2, 28, "Topics: 4.1.1 | 4.1.2 | 4.1.3 | 4.1.4")
            c.drawCentredString(w/2, 16, "Includes Diagrams | Flowcharts | Key Points | MCQ Tips")

    story.append(CoverPage())
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════
    # TABLE OF CONTENTS
    # ══════════════════════════════════════════════════════════════
    story.append(SectionHeader("TABLE OF CONTENTS", C_NAVY, "Module 4.1 - ANS & Autacoids"))
    story.append(sp(10))
    toc_data = [
        [Paragraph("<b>Section</b>", TABLE_HDR), Paragraph("<b>Topic</b>", TABLE_HDR), Paragraph("<b>Page</b>", TABLE_HDR)],
        [Paragraph("4.1.1", TABLE_CELL_C), Paragraph("Cholinergic & Anticholinergic Drugs", TABLE_CELL), Paragraph("3", TABLE_CELL_C)],
        [Paragraph("4.1.2", TABLE_CELL_C), Paragraph("Adrenergic & Antiadrenergic Drugs", TABLE_CELL), Paragraph("5", TABLE_CELL_C)],
        [Paragraph("4.1.3", TABLE_CELL_C), Paragraph("Serotonin & Serotonergic Drugs (SSRIs, SNRIs, Triptans)", TABLE_CELL), Paragraph("8", TABLE_CELL_C)],
        [Paragraph("4.1.4", TABLE_CELL_C), Paragraph("Histamine & Antihistaminics", TABLE_CELL), Paragraph("10", TABLE_CELL_C)],
        [Paragraph("4.1.4", TABLE_CELL_C), Paragraph("Migraine - Pathophysiology & Treatment", TABLE_CELL), Paragraph("11", TABLE_CELL_C)],
        [Paragraph("—", TABLE_CELL_C), Paragraph("Exam Quick Reference & MCQ Tips", TABLE_CELL), Paragraph("13", TABLE_CELL_C)],
    ]
    toc_table = Table(toc_data, colWidths=[2*cm, 12*cm, 2*cm])
    toc_table.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_NAVY),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_LIGHTBLUE]),
        ("GRID", (0,0), (-1,-1), 0.5, HexColor("#BBDEFB")),
        ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTNAME", (0,1), (-1,-1), "Helvetica"),
        ("FONTSIZE", (0,0), (-1,-1), 9.5),
        ("ROWHEIGHT", (0,0), (-1,-1), 18),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROUNDEDCORNERS", [4,4,4,4]),
    ]))
    story.append(toc_table)
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════
    # SECTION 1: ANS OVERVIEW
    # ══════════════════════════════════════════════════════════════
    story.append(SectionHeader("ANS OVERVIEW", C_NAVY, "Autonomic Nervous System - Foundation"))
    story.append(sp(8))
    story.append(Paragraph("The <b>Autonomic Nervous System (ANS)</b> is the involuntary division of the peripheral nervous system that regulates visceral functions. It is divided into two main divisions that often oppose each other.", BODY))
    story.append(sp(6))
    story.append(ANSNervesDiagram(width=W - 3.6*cm - 0))
    story.append(sp(8))

    ans_overview = [
        [Paragraph("<b>Feature</b>", TABLE_HDR), Paragraph("<b>Parasympathetic (PNS)</b>", TABLE_HDR), Paragraph("<b>Sympathetic (SNS)</b>", TABLE_HDR)],
        [Paragraph("Origin", BODY_BOLD), Paragraph("Craniosacral (CN III, VII, IX, X + S2-S4)", BODY), Paragraph("Thoracolumbar (T1-L2)", BODY)],
        [Paragraph("Neurotransmitter", BODY_BOLD), Paragraph("Acetylcholine (ACh) - all synapses", BODY), Paragraph("NE (postganglionic), ACh (ganglionic)", BODY)],
        [Paragraph("Receptors", BODY_BOLD), Paragraph("Muscarinic (M1-M5) + Nicotinic (Nm, Nn)", BODY), Paragraph("α1, α2, β1, β2, β3 adrenoceptors", BODY)],
        [Paragraph("Overall Effect", BODY_BOLD), Paragraph("Rest & Digest: ↓HR, ↑GI, constrict pupil", BODY), Paragraph("Fight or Flight: ↑HR, bronchodilate, ↑BP", BODY)],
        [Paragraph("Ganglia", BODY_BOLD), Paragraph("Terminal ganglia (near target organ)", BODY), Paragraph("Paravertebral ganglia (far from target)", BODY)],
    ]
    ans_table = Table(ans_overview, colWidths=[3.5*cm, 7.5*cm, 7.5*cm])
    ans_table.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_NAVY),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_GREY_LT]),
        ("GRID", (0,0), (-1,-1), 0.5, HexColor("#BBDEFB")),
        ("FONTSIZE", (0,0), (-1,-1), 8.5),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 16),
    ]))
    story.append(ans_table)
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════
    # SECTION 2: CHOLINERGIC DRUGS (4.1.1)
    # ══════════════════════════════════════════════════════════════
    story.append(SectionHeader("4.1.1 - CHOLINERGIC DRUGS", C_TEAL, "Parasympathomimetics - Agonists & Indirect"))
    story.append(sp(6))

    story.append(Paragraph("Cholinergic drugs <b>mimic ACh</b> or enhance its activity. They activate muscarinic and/or nicotinic receptors.", BODY))
    story.append(sp(4))

    # Classification flowchart
    story.append(Paragraph("<b>Classification of Cholinergic Drugs</b>", H3))
    chol_steps = [
        ("CHOLINERGIC DRUGS (Parasympathomimetics)", C_TEAL),
        ("Direct-Acting: Bind directly to cholinergic receptors", HexColor("#00897B")),
        ("Muscarinic Agonists: Pilocarpine, Bethanechol, Carbachol, Muscarine", HexColor("#2E7D32")),
        ("Nicotinic Agonists: Nicotine, Succinylcholine (at NMJ)", HexColor("#388E3C")),
        ("Indirect-Acting: Inhibit AChE → ↑ ACh at synapse", HexColor("#1B5E20")),
        ("Reversible AChE Inhibitors: Neostigmine, Physostigmine, Pyridostigmine, Edrophonium", HexColor("#00695C")),
        ("Irreversible AChE Inhibitors (Organophosphates): Echothiophate, Malathion, Sarin", C_RED),
    ]
    story.append(DiagramFlowchart(chol_steps, width=W - 3.6*cm))
    story.append(sp(8))

    # Muscarinic Effects Table (SLUDGE)
    story.append(Paragraph("<b>Muscarinic Effects - SLUDGE Mnemonic</b>", H3))
    sludge_data = [
        [Paragraph("<b>Letter</b>", TABLE_HDR), Paragraph("<b>Effect</b>", TABLE_HDR), Paragraph("<b>System</b>", TABLE_HDR), Paragraph("<b>Clinical Use</b>", TABLE_HDR)],
        [Paragraph("S - Salivation", BODY_BOLD), Paragraph("↑ saliva secretion", BODY), Paragraph("Salivary glands", BODY), Paragraph("Dry mouth reversal", BODY)],
        [Paragraph("L - Lacrimation", BODY_BOLD), Paragraph("↑ tear production", BODY), Paragraph("Lacrimal glands", BODY), Paragraph("Dry eye conditions", BODY)],
        [Paragraph("U - Urination", BODY_BOLD), Paragraph("↑ bladder contraction", BODY), Paragraph("Urinary bladder", BODY), Paragraph("Urinary retention (Bethanechol)", BODY)],
        [Paragraph("D - Defecation", BODY_BOLD), Paragraph("↑ GI motility", BODY), Paragraph("GI tract", BODY), Paragraph("Paralytic ileus", BODY)],
        [Paragraph("G - GI cramps", BODY_BOLD), Paragraph("↑ peristalsis", BODY), Paragraph("Intestines", BODY), Paragraph("Constipation", BODY)],
        [Paragraph("E - Emesis", BODY_BOLD), Paragraph("↑ vomiting reflex", BODY), Paragraph("GI/CNS", BODY), Paragraph("Nausea side effect", BODY)],
    ]
    sludge_table = Table(sludge_data, colWidths=[3.5*cm, 4*cm, 4*cm, 5*cm])
    sludge_table.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_TEAL),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_TEAL_LT, C_WHITE]),
        ("GRID", (0,0), (-1,-1), 0.5, C_TEAL),
        ("FONTSIZE", (0,0), (-1,-1), 8.5),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 15),
    ]))
    story.append(sludge_table)
    story.append(sp(8))

    # Key drugs table
    story.append(Paragraph("<b>Key Cholinergic Drugs & Clinical Uses</b>", H3))
    chol_drugs = [
        [Paragraph("<b>Drug</b>", TABLE_HDR), Paragraph("<b>Class</b>", TABLE_HDR), Paragraph("<b>Mechanism</b>", TABLE_HDR), Paragraph("<b>Clinical Uses</b>", TABLE_HDR), Paragraph("<b>Key Side Effects</b>", TABLE_HDR)],
        [Paragraph("Pilocarpine", BODY_BOLD), Paragraph("Direct M-agonist", BODY), Paragraph("M3 agonist → miosis + ↑aqueous outflow", BODY), Paragraph("Glaucoma, Sjogren's", BODY), Paragraph("Sweating, bradycardia", BODY)],
        [Paragraph("Bethanechol", BODY_BOLD), Paragraph("Direct M-agonist", BODY), Paragraph("M3 agonist → bladder contraction", BODY), Paragraph("Urinary retention, Ileus", BODY), Paragraph("Diarrhea, cramps", BODY)],
        [Paragraph("Neostigmine", BODY_BOLD), Paragraph("Reversible AChEI", BODY), Paragraph("Inhibits AChE reversibly", BODY), Paragraph("Myasthenia gravis, NMJ reversal", BODY), Paragraph("SLUDGE effects", BODY)],
        [Paragraph("Pyridostigmine", BODY_BOLD), Paragraph("Reversible AChEI", BODY), Paragraph("Long-acting AChE inhibitor", BODY), Paragraph("Myasthenia gravis (preferred)", BODY), Paragraph("GI upset, bradycardia", BODY)],
        [Paragraph("Physostigmine", BODY_BOLD), Paragraph("Reversible AChEI", BODY), Paragraph("CNS-penetrating AChEI", BODY), Paragraph("Atropine OD, Glaucoma", BODY), Paragraph("Seizures in overdose", BODY)],
        [Paragraph("Donepezil", BODY_BOLD), Paragraph("Reversible AChEI", BODY), Paragraph("CNS-selective AChEI", BODY), Paragraph("Alzheimer's dementia", BODY), Paragraph("Nausea, insomnia", BODY)],
    ]
    ct = Table(chol_drugs, colWidths=[3*cm, 3*cm, 4.5*cm, 3.5*cm, 3*cm])
    ct.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_TEAL),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_TEAL_LT]),
        ("GRID", (0,0), (-1,-1), 0.4, C_TEAL),
        ("FONTSIZE", (0,0), (-1,-1), 8),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 18),
    ]))
    story.append(ct)
    story.append(sp(6))
    story.append(Paragraph("<b>★ EXAM TIP:</b> SLUDGE = Salivation, Lacrimation, Urination, Defecation, GI cramps, Emesis - all cholinergic toxicity signs!", EXAM_TIP))
    story.append(Paragraph("<b>★ EXAM TIP:</b> Neostigmine cannot cross BBB; Physostigmine CAN cross BBB → used for CNS atropine toxicity.", EXAM_TIP))
    story.append(PageBreak())

    # ── ANTICHOLINERGIC DRUGS ──
    story.append(SectionHeader("4.1.1b - ANTICHOLINERGIC DRUGS", C_ORANGE, "Parasympatholytics - Muscarinic Antagonists"))
    story.append(sp(6))
    story.append(Paragraph("Anticholinergic drugs <b>block muscarinic receptors</b> (M1-M5), opposing parasympathetic effects. They produce the 'anti-SLUDGE' picture.", BODY))
    story.append(sp(4))

    # Anti-SLUDGE Mnemonic - visual
    story.append(Paragraph("<b>Anticholinergic Effects - 'Dry as a Bone' Mnemonic</b>", H3))
    mnemonic_data = [
        [Paragraph("<b>Mnemonic</b>", TABLE_HDR), Paragraph("<b>Effect</b>", TABLE_HDR), Paragraph("<b>Clinical Relevance</b>", TABLE_HDR)],
        [Paragraph("Dry as a Bone", BODY_BOLD), Paragraph("↓ secretions (dry mouth, dry skin, no sweating)", BODY), Paragraph("Heat intolerance, xerostomia", BODY)],
        [Paragraph("Red as a Beet", BODY_BOLD), Paragraph("Flushing (cutaneous vasodilation)", BODY), Paragraph("Atropine overdose sign", BODY)],
        [Paragraph("Hot as a Hare", BODY_BOLD), Paragraph("Hyperthermia (↓ sweating)", BODY), Paragraph("Dangerous in hot weather", BODY)],
        [Paragraph("Blind as a Bat", BODY_BOLD), Paragraph("Mydriasis + cycloplegia (blurred near vision)", BODY), Paragraph("Pre-op mydriasis, caution in glaucoma", BODY)],
        [Paragraph("Mad as a Hatter", BODY_BOLD), Paragraph("CNS excitation/confusion (esp. in elderly)", BODY), Paragraph("Delirium in geriatric patients", BODY)],
        [Paragraph("Full as a Flask", BODY_BOLD), Paragraph("Urinary retention", BODY), Paragraph("Caution in BPH patients", BODY)],
    ]
    mt = Table(mnemonic_data, colWidths=[4*cm, 6.5*cm, 6*cm])
    mt.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_ORANGE),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_ORANGE_LT, C_WHITE]),
        ("GRID", (0,0), (-1,-1), 0.4, C_ORANGE),
        ("FONTSIZE", (0,0), (-1,-1), 8.5),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 18),
    ]))
    story.append(mt)
    story.append(sp(8))

    story.append(Paragraph("<b>Key Anticholinergic Drugs</b>", H3))
    anti_drugs = [
        [Paragraph("<b>Drug</b>", TABLE_HDR), Paragraph("<b>Selectivity</b>", TABLE_HDR), Paragraph("<b>Clinical Uses</b>", TABLE_HDR), Paragraph("<b>Notes</b>", TABLE_HDR)],
        [Paragraph("Atropine", BODY_BOLD), Paragraph("Non-selective M-blocker", BODY), Paragraph("Bradycardia, Organophosphate poisoning, Pre-op", BODY), Paragraph("DOC for OP poisoning; crosses BBB", BODY)],
        [Paragraph("Scopolamine", BODY_BOLD), Paragraph("M1 preference", BODY), Paragraph("Motion sickness, post-op nausea", BODY), Paragraph("Transdermal patch; CNS depressant", BODY)],
        [Paragraph("Ipratropium", BODY_BOLD), Paragraph("M3 in airways", BODY), Paragraph("COPD, Asthma (bronchodilator)", BODY), Paragraph("Inhaled; minimal systemic effects", BODY)],
        [Paragraph("Tiotropium", BODY_BOLD), Paragraph("M1/M3 blocker", BODY), Paragraph("COPD (long-acting)", BODY), Paragraph("Once daily dosing; preferred in COPD", BODY)],
        [Paragraph("Benztropine", BODY_BOLD), Paragraph("M1 in CNS", BODY), Paragraph("Parkinson's disease", BODY), Paragraph("Reduces tremor; CNS penetrating", BODY)],
        [Paragraph("Oxybutynin", BODY_BOLD), Paragraph("M3 in bladder", BODY), Paragraph("Overactive bladder, urge incontinence", BODY), Paragraph("Dry mouth most common SE", BODY)],
    ]
    adt = Table(anti_drugs, colWidths=[3*cm, 3.5*cm, 5.5*cm, 5.5*cm])
    adt.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_ORANGE),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_ORANGE_LT]),
        ("GRID", (0,0), (-1,-1), 0.4, C_ORANGE),
        ("FONTSIZE", (0,0), (-1,-1), 8.5),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 18),
    ]))
    story.append(adt)
    story.append(sp(6))
    story.append(Paragraph("<b>★ EXAM TIP:</b> Anticholinergic = anti-SLUDGE. Key differences: Ipratropium (inhaled for COPD) vs. Atropine (systemic). Scopolamine = motion sickness patch.", EXAM_TIP))
    story.append(Paragraph("<b>★ EXAM TIP:</b> Contraindications: Angle-closure glaucoma, BPH, paralytic ileus, tachycardia.", EXAM_TIP))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════
    # SECTION 3: ADRENERGIC DRUGS (4.1.2)
    # ══════════════════════════════════════════════════════════════
    story.append(SectionHeader("4.1.2 - ADRENERGIC DRUGS", C_RED, "Sympathomimetics - Agonists & Mechanisms"))
    story.append(sp(6))
    story.append(Paragraph("Adrenergic drugs act on <b>adrenoceptors (α and β)</b>, mimicking or blocking SNS activity. They are classified by receptor selectivity.", BODY))
    story.append(sp(6))
    story.append(ReceptorDiagram(width=W - 3.6*cm))
    story.append(sp(8))

    story.append(Paragraph("<b>Classification of Adrenergic Agonists</b>", H3))
    adr_steps = [
        ("ADRENERGIC AGONISTS (Sympathomimetics)", C_RED),
        ("Direct-Acting: Bind directly to adrenoceptors", HexColor("#C62828")),
        ("Non-selective: Epinephrine (α+β), Norepinephrine (α1+α2+β1), Isoproterenol (β1+β2)", HexColor("#AD1457")),
        ("Alpha-selective: Phenylephrine (α1), Clonidine (α2)", HexColor("#6A1B9A")),
        ("Beta-selective: Salbutamol/Albuterol (β2), Dobutamine (β1), Metaproterenol (β2)", C_BLUE),
        ("Indirect-Acting: Stimulate NE release or block reuptake", HexColor("#37474F")),
        ("Amphetamine (NE release), Cocaine (reuptake blocker), Tyramine (NE release)", HexColor("#546E7A")),
        ("Mixed-Acting: Both direct & indirect", C_TEAL),
        ("Ephedrine, Pseudoephedrine (direct + NE release)", HexColor("#00695C")),
    ]
    story.append(DiagramFlowchart(adr_steps, width=W - 3.6*cm))
    story.append(sp(8))

    story.append(Paragraph("<b>Key Adrenergic Agonists - Clinical Uses</b>", H3))
    adr_drugs = [
        [Paragraph("<b>Drug</b>", TABLE_HDR), Paragraph("<b>Receptors</b>", TABLE_HDR), Paragraph("<b>Effects</b>", TABLE_HDR), Paragraph("<b>Clinical Uses</b>", TABLE_HDR)],
        [Paragraph("Epinephrine", BODY_BOLD), Paragraph("α1, α2, β1, β2", BODY), Paragraph("↑HR, bronchodilation, vasoconstriction", BODY), Paragraph("Anaphylaxis (DOC), Cardiac arrest, Asthma", BODY)],
        [Paragraph("Norepinephrine", BODY_BOLD), Paragraph("α1, α2, β1 (weak β2)", BODY), Paragraph("↑BP, reflex bradycardia, vasoconstriction", BODY), Paragraph("Septic shock, vasopressor", BODY)],
        [Paragraph("Dopamine", BODY_BOLD), Paragraph("D1, β1 (low dose), α1 (high dose)", BODY), Paragraph("Dose-dependent effects", BODY), Paragraph("Cardiogenic shock, acute HF, renal dose", BODY)],
        [Paragraph("Dobutamine", BODY_BOLD), Paragraph("β1 selective", BODY), Paragraph("↑Contractility (inotrope), ↑HR", BODY), Paragraph("Acute heart failure, cardiogenic shock", BODY)],
        [Paragraph("Salbutamol", BODY_BOLD), Paragraph("β2 selective", BODY), Paragraph("Bronchodilation, uterine relaxation", BODY), Paragraph("Asthma (DOC), COPD, Tocolysis", BODY)],
        [Paragraph("Phenylephrine", BODY_BOLD), Paragraph("α1 selective", BODY), Paragraph("Vasoconstriction, ↑BP, mydriasis", BODY), Paragraph("Nasal decongestant, hypotension, mydriasis", BODY)],
        [Paragraph("Clonidine", BODY_BOLD), Paragraph("α2 (CNS)", BODY), Paragraph("↓Sympathetic outflow, ↓BP, ↓HR", BODY), Paragraph("Hypertension, ADHD, opioid withdrawal", BODY)],
    ]
    adrt = Table(adr_drugs, colWidths=[3*cm, 3.5*cm, 5*cm, 5*cm])
    adrt.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_RED),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_RED_LT]),
        ("GRID", (0,0), (-1,-1), 0.4, HexColor("#EF9A9A")),
        ("FONTSIZE", (0,0), (-1,-1), 8),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 18),
    ]))
    story.append(adrt)
    story.append(sp(6))
    story.append(Paragraph("<b>★ EXAM TIP:</b> Epinephrine = DOC for anaphylaxis. Dobutamine = inotrope (β1). Salbutamol = bronchodilator (β2). Phenylephrine = pure α1 agonist.", EXAM_TIP))
    story.append(Paragraph("<b>★ Dopamine Dose Rule:</b> Low dose (renal/D1), Medium dose (cardiac/β1), High dose (vasopressor/α1).", EXAM_TIP))
    story.append(PageBreak())

    # ── ANTIADRENERGIC DRUGS ──
    story.append(SectionHeader("4.1.2b - ANTIADRENERGIC DRUGS", HexColor("#880E4F"), "Alpha & Beta Blockers"))
    story.append(sp(6))
    story.append(Paragraph("Antiadrenergic drugs <b>block adrenoceptors</b> or reduce SNS outflow. They oppose sympathetic effects - reducing HR, BP, and cardiac output.", BODY))
    story.append(sp(4))

    story.append(Paragraph("<b>Alpha Blockers (α-antagonists)</b>", H3))
    alpha_data = [
        [Paragraph("<b>Drug</b>", TABLE_HDR), Paragraph("<b>Selectivity</b>", TABLE_HDR), Paragraph("<b>Uses</b>", TABLE_HDR), Paragraph("<b>Side Effects</b>", TABLE_HDR)],
        [Paragraph("Prazosin", BODY_BOLD), Paragraph("Selective α1", BODY), Paragraph("Hypertension, BPH", BODY), Paragraph("First-dose hypotension, dizziness", BODY)],
        [Paragraph("Tamsulosin", BODY_BOLD), Paragraph("Selective α1A (prostate)", BODY), Paragraph("BPH (preferred)", BODY), Paragraph("Retrograde ejaculation", BODY)],
        [Paragraph("Doxazosin", BODY_BOLD), Paragraph("Selective α1", BODY), Paragraph("Hypertension, BPH", BODY), Paragraph("Postural hypotension", BODY)],
        [Paragraph("Phentolamine", BODY_BOLD), Paragraph("Non-selective α1+α2", BODY), Paragraph("Pheochromocytoma (pre-op), HA crisis", BODY), Paragraph("Reflex tachycardia, nasal stuffiness", BODY)],
        [Paragraph("Phenoxybenzamine", BODY_BOLD), Paragraph("Irreversible α1+α2", BODY), Paragraph("Pheochromocytoma (long-term)", BODY), Paragraph("Prolonged hypotension", BODY)],
    ]
    at = Table(alpha_data, colWidths=[3.5*cm, 3.5*cm, 5.5*cm, 5*cm])
    at.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), HexColor("#880E4F")),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_PURPLE_LT]),
        ("GRID", (0,0), (-1,-1), 0.4, HexColor("#CE93D8")),
        ("FONTSIZE", (0,0), (-1,-1), 8.5),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 18),
    ]))
    story.append(at)
    story.append(sp(8))

    story.append(Paragraph("<b>Beta Blockers (β-antagonists) - Classified by Selectivity</b>", H3))
    beta_steps = [
        ("BETA BLOCKERS (Sympatholytics)", HexColor("#1A237E")),
        ("NON-SELECTIVE (β1 + β2): Propranolol, Timolol, Nadolol, Carvedilol (also α1)", HexColor("#283593")),
        ("SELECTIVE β1 (Cardioselective): Atenolol, Metoprolol, Bisoprolol, Esmolol, Nebivolol", C_BLUE),
        ("Mechanism: Compete with catecholamines at β receptors → ↓HR, ↓contractility, ↓BP", HexColor("#0277BD")),
        ("Clinical Uses: HTN, Angina, Post-MI, CHF, Arrhythmias, Thyrotoxicosis, Glaucoma (Timolol)", C_TEAL),
        ("Adverse Effects: Bradycardia, Hypotension, Fatigue, Bronchoconstriction (non-selective)", C_RED),
        ("CONTRAINDICATED in: Asthma, AV block, Acute decompensated heart failure, Prinzmetal angina", HexColor("#B71C1C")),
    ]
    story.append(DiagramFlowchart(beta_steps, width=W - 3.6*cm))
    story.append(sp(6))
    story.append(Paragraph("<b>★ EXAM TIP:</b> Selective β1 blockers (Metoprolol, Atenolol) are safer in asthma patients. Carvedilol = α1+β - used in heart failure. Propranolol = prototype non-selective β blocker.", EXAM_TIP))
    story.append(Paragraph("<b>★ EXAM TIP:</b> Non-selective β blockers are CONTRAINDICATED in asthma (block β2 → bronchoconstriction).", EXAM_TIP))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════
    # SECTION 4: SEROTONIN & SEROTONERGIC DRUGS (4.1.3)
    # ══════════════════════════════════════════════════════════════
    story.append(SectionHeader("4.1.3 - SEROTONIN & SEROTONERGIC DRUGS", C_PURPLE, "SSRIs, SNRIs, Triptans & Modulators"))
    story.append(sp(6))
    story.append(Paragraph("Serotonin (5-Hydroxytryptamine, <b>5-HT</b>) is a monoamine neurotransmitter synthesized from tryptophan. It acts in both CNS (mood, sleep, appetite) and periphery (GI motility, platelet aggregation).", BODY))
    story.append(sp(4))
    story.append(Paragraph("<b>Serotonin Synthesis & Reuptake Pathway</b>", H3))
    story.append(SerotoninPathway(width=W - 3.6*cm))
    story.append(sp(8))

    story.append(Paragraph("<b>Classification of Serotonergic Drugs</b>", H3))
    sero_class = [
        [Paragraph("<b>Class</b>", TABLE_HDR), Paragraph("<b>Drugs</b>", TABLE_HDR), Paragraph("<b>Mechanism</b>", TABLE_HDR), Paragraph("<b>Clinical Use</b>", TABLE_HDR)],
        [Paragraph("SSRIs", BODY_BOLD), Paragraph("Fluoxetine, Sertraline, Paroxetine, Escitalopram, Citalopram", BODY), Paragraph("Block SERT → ↑ synaptic 5-HT", BODY), Paragraph("Depression, OCD, Panic disorder, PTSD, Social anxiety", BODY)],
        [Paragraph("SNRIs", BODY_BOLD), Paragraph("Venlafaxine, Duloxetine, Desvenlafaxine", BODY), Paragraph("Block SERT + NET → ↑5-HT + ↑NE", BODY), Paragraph("Depression, GAD, Neuropathic pain, Fibromyalgia", BODY)],
        [Paragraph("5-HT1 Agonists (Triptans)", BODY_BOLD), Paragraph("Sumatriptan, Rizatriptan, Zolmitriptan, Almotriptan", BODY), Paragraph("5-HT1B/1D agonism → vasoconstriction + inhibit CGRP release", BODY), Paragraph("Acute migraine, Cluster headache", BODY)],
        [Paragraph("5-HT3 Antagonists", BODY_BOLD), Paragraph("Ondansetron, Granisetron, Palonosetron", BODY), Paragraph("Block 5-HT3 in CTZ and vagal afferents", BODY), Paragraph("Chemotherapy-induced N&V, post-op nausea", BODY)],
        [Paragraph("5-HT4 Agonists", BODY_BOLD), Paragraph("Metoclopramide (partial), Mosapride, Tegaserod", BODY), Paragraph("5-HT4 agonism → ↑GI motility/peristalsis", BODY), Paragraph("GERD, IBS-C, gastroparesis", BODY)],
        [Paragraph("Serotonin Modulators", BODY_BOLD), Paragraph("Buspirone, Mirtazapine, Trazodone, Vilazodone", BODY), Paragraph("Mixed 5-HT agonist/antagonist + reuptake block", BODY), Paragraph("Anxiety, Depression (with sleep disturbance)", BODY)],
    ]
    st = Table(sero_class, colWidths=[3*cm, 4*cm, 5*cm, 4.5*cm])
    st.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_PURPLE),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_PURPLE_LT]),
        ("GRID", (0,0), (-1,-1), 0.4, HexColor("#CE93D8")),
        ("FONTSIZE", (0,0), (-1,-1), 8),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 22),
    ]))
    story.append(st)
    story.append(sp(6))
    story.append(Paragraph("<b>★ EXAM TIP:</b> SSRIs are FIRST-LINE for depression, OCD, anxiety disorders. Take 2-6 weeks for full effect. Risk: Serotonin syndrome (hyperthermia, hypertension, myoclonus, confusion).", EXAM_TIP))
    story.append(Paragraph("<b>★ Serotonin Syndrome Triad:</b> (1) Altered mental status, (2) Autonomic instability, (3) Neuromuscular abnormalities. Treat with Cyproheptadine (5-HT antagonist).", EXAM_TIP))
    story.append(Paragraph("<b>★ EXAM TIP:</b> Triptans contraindicated in: Ischemic heart disease, uncontrolled HTN, basilar/hemiplegic migraine, pregnancy (relative).", EXAM_TIP))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════
    # SECTION 5: HISTAMINE & ANTIHISTAMINICS (4.1.4)
    # ══════════════════════════════════════════════════════════════
    story.append(SectionHeader("4.1.4 - HISTAMINE & ANTIHISTAMINICS", C_YELLOW, "H1, H2 Receptors & Drug Classification"))
    story.append(sp(6))
    story.append(Paragraph("Histamine is an autacoid stored in mast cells and basophils. It plays roles in allergic reactions, gastric acid secretion, neurotransmission, and immune responses.", BODY))
    story.append(sp(4))

    hist_class = [
        [Paragraph("<b>Receptor</b>", TABLE_HDR), Paragraph("<b>Location</b>", TABLE_HDR), Paragraph("<b>Effects when activated</b>", TABLE_HDR), Paragraph("<b>Blocked by</b>", TABLE_HDR)],
        [Paragraph("H1", BODY_BOLD), Paragraph("Smooth muscle, endothelium, CNS", BODY), Paragraph("Bronchoconstriction, vasodilation, itch, pain, allergy symptoms", BODY), Paragraph("H1 antihistamines (1st & 2nd gen)", BODY)],
        [Paragraph("H2", BODY_BOLD), Paragraph("Gastric parietal cells, heart", BODY), Paragraph("↑ Gastric acid secretion, ↑ HR", BODY), Paragraph("H2 blockers (Ranitidine, Famotidine)", BODY)],
        [Paragraph("H3", BODY_BOLD), Paragraph("Presynaptic CNS neurons", BODY), Paragraph("Inhibit histamine release (autoreceptor), modulate CNS NT", BODY), Paragraph("Pitolisant (narcolepsy)", BODY)],
        [Paragraph("H4", BODY_BOLD), Paragraph("Immune cells, GI tract", BODY), Paragraph("Immune modulation, eosinophil chemotaxis", BODY), Paragraph("Research / investigational agents", BODY)],
    ]
    ht = Table(hist_class, colWidths=[2*cm, 4*cm, 5.5*cm, 5*cm])
    ht.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_YELLOW),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_YELLOW_LT, C_WHITE]),
        ("GRID", (0,0), (-1,-1), 0.4, C_YELLOW),
        ("FONTSIZE", (0,0), (-1,-1), 8.5),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 20),
    ]))
    story.append(ht)
    story.append(sp(8))

    story.append(Paragraph("<b>Antihistaminic Drugs - Classification</b>", H3))
    anti_hist = [
        [Paragraph("<b>Generation</b>", TABLE_HDR), Paragraph("<b>Drugs</b>", TABLE_HDR), Paragraph("<b>Properties</b>", TABLE_HDR), Paragraph("<b>Clinical Uses</b>", TABLE_HDR)],
        [Paragraph("1st Generation\n(Sedating)", BODY_BOLD), Paragraph("Diphenhydramine\nChlorpheniramine\nPromethazine\nCyproheptadine\nHydroxyzine", BODY), Paragraph("- Cross BBB → sedation\n- Anticholinergic effects\n- Short duration (4-6h)", BODY), Paragraph("Allergic rhinitis, Urticaria, Anaphylaxis (adjunct), Motion sickness, Sleep aid, Cold/flu", BODY)],
        [Paragraph("2nd Generation\n(Non-sedating)", BODY_BOLD), Paragraph("Cetirizine\nFexofenadine\nLoratadine\nBilastine\nAzelastine", BODY), Paragraph("- Poor BBB penetration\n- No anticholinergic effects\n- Long duration (12-24h)\n- Preferred clinically", BODY), Paragraph("Allergic rhinitis (preferred), Urticaria (chronic), Hay fever, Allergic conjunctivitis", BODY)],
        [Paragraph("H2 Blockers\n(Gastric)", BODY_BOLD), Paragraph("Ranitidine\nFamotidine\nCimetidine\nNizatidine", BODY), Paragraph("- Block H2 → ↓gastric acid\n- No H1 activity\n- Cimetidine: multiple DDI", BODY), Paragraph("Peptic ulcer, GERD, Zollinger-Ellison, Upper GI bleeding", BODY)],
    ]
    aht = Table(anti_hist, colWidths=[3*cm, 3.5*cm, 5*cm, 5*cm])
    aht.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_YELLOW),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_YELLOW_LT]),
        ("GRID", (0,0), (-1,-1), 0.4, C_YELLOW),
        ("FONTSIZE", (0,0), (-1,-1), 8),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 60),
    ]))
    story.append(aht)
    story.append(sp(6))
    story.append(Paragraph("<b>★ EXAM TIP:</b> Diphenhydramine = 1st gen, sedating, anticholinergic. Fexofenadine = 2nd gen, non-sedating, preferred. Cyproheptadine = also used in Serotonin syndrome + appetite stimulant.", EXAM_TIP))
    story.append(Paragraph("<b>★ EXAM TIP:</b> Cimetidine inhibits CYP450 → multiple drug interactions. Famotidine has fewest drug interactions among H2 blockers.", EXAM_TIP))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════
    # SECTION 6: MIGRAINE (4.1.4)
    # ══════════════════════════════════════════════════════════════
    story.append(SectionHeader("MIGRAINE - Pathophysiology & Treatment", HexColor("#880E4F"), "Acute & Preventive Therapies | CGRP | Triptans"))
    story.append(sp(6))
    story.append(Paragraph("<b>Pathophysiology of Migraine</b>", H3))
    story.append(Paragraph("Migraine is a <b>neurovascular disorder</b> involving abnormal activation of the trigeminovascular system, cortical spreading depression, and release of neuropeptides (CGRP, Substance P).", BODY))
    story.append(sp(6))

    # Two-column layout: Flowchart + Types
    class TwoColumnFlowable(Flowable):
        def __init__(self, left_items, right_items, col_width, height, left_title, right_title):
            super().__init__()
            self._cw = col_width
            self._h = height
            self.left_items = left_items
            self.right_items = right_items
            self.lt = left_title
            self.rt = right_title

        def wrap(self, aw, ah):
            self.width = aw
            self.height = self._h
            return aw, self._h

        def draw(self):
            c = self.canv
            w = self.width
            mid = w / 2 - 5

            # Left panel
            c.setFillColor(HexColor("#FCE4EC"))
            c.roundRect(0, 0, mid, self._h, 6, fill=1, stroke=0)
            c.setFillColor(HexColor("#880E4F"))
            c.roundRect(0, self._h - 24, mid, 24, 6, fill=1, stroke=0)
            c.setFillColor(C_WHITE)
            c.setFont("Helvetica-Bold", 9)
            c.drawCentredString(mid/2, self._h - 10, self.lt)

            for i, (label, detail) in enumerate(self.left_items):
                y = self._h - 40 - i * 28
                c.setFillColor(HexColor("#880E4F"))
                c.roundRect(8, y, mid - 16, 22, 3, fill=1, stroke=0)
                c.setFillColor(C_WHITE)
                c.setFont("Helvetica-Bold", 8)
                c.drawString(16, y + 12, label)
                c.setFont("Helvetica", 7.5)
                c.drawString(16, y + 3, detail)

            # Right panel
            c.setFillColor(HexColor("#E8F5E9"))
            c.roundRect(mid + 10, 0, w - mid - 10, self._h, 6, fill=1, stroke=0)
            c.setFillColor(C_GREEN)
            c.roundRect(mid + 10, self._h - 24, w - mid - 10, 24, 6, fill=1, stroke=0)
            c.setFillColor(C_WHITE)
            c.setFont("Helvetica-Bold", 9)
            c.drawCentredString(mid + 10 + (w - mid - 10)/2, self._h - 10, self.rt)

            for i, (label, detail) in enumerate(self.right_items):
                y = self._h - 40 - i * 28
                c.setFillColor(C_GREEN)
                c.roundRect(mid + 18, y, w - mid - 26, 22, 3, fill=1, stroke=0)
                c.setFillColor(C_WHITE)
                c.setFont("Helvetica-Bold", 8)
                c.drawString(mid + 26, y + 12, label)
                c.setFont("Helvetica", 7.5)
                c.drawString(mid + 26, y + 3, detail)

    migraine_types = [
        ("Migraine with Aura", "Visual/sensory/motor symptoms 20-60 min before headache"),
        ("Migraine without Aura", "No prodromal neurological symptoms; most common type"),
        ("Chronic Migraine", "≥15 headache days/month for >3 months"),
        ("Basilar Migraine", "Brainstem aura; diplopia, vertigo, dysarthria"),
        ("Hemiplegic Migraine", "Motor weakness; CACNA1A/ATP1A2 gene mutations"),
    ]
    migraine_triggers = [
        ("Hormonal", "Estrogen fluctuations, menstruation, OCPs"),
        ("Dietary", "Tyramine, alcohol, caffeine withdrawal, MSG"),
        ("Environmental", "Bright lights, strong odors, weather changes"),
        ("Stress", "Emotional stress, sleep deprivation, fatigue"),
        ("Pharmacological", "Analgesic overuse (MOH), nitrates, vasodilators"),
    ]
    story.append(TwoColumnFlowable(migraine_types, migraine_triggers, 
                                    W/2, 180, "MIGRAINE TYPES", "COMMON TRIGGERS"))
    story.append(sp(8))

    story.append(Paragraph("<b>Migraine Pathophysiology Flowchart</b>", H3))
    story.append(MigrainePathway(width=W - 3.6*cm))
    story.append(sp(8))

    story.append(Paragraph("<b>Treatment of Migraine - Acute vs. Preventive</b>", H3))
    migraine_tx = [
        [Paragraph("<b>Category</b>", TABLE_HDR), Paragraph("<b>Drug Class</b>", TABLE_HDR), Paragraph("<b>Drugs</b>", TABLE_HDR), Paragraph("<b>Mechanism</b>", TABLE_HDR)],
        [Paragraph("ACUTE\nTreatment", BODY_BOLD), Paragraph("Triptans (DOC for moderate-severe)", BODY), Paragraph("Sumatriptan, Rizatriptan, Zolmitriptan, Eletriptan", BODY), Paragraph("5-HT1B/1D agonist → vasoconstriction, ↓CGRP", BODY)],
        [Paragraph("ACUTE", BODY_BOLD), Paragraph("NSAIDs (mild-moderate)", BODY), Paragraph("Ibuprofen, Naproxen, Aspirin, Diclofenac", BODY), Paragraph("COX inhibition → ↓prostaglandins", BODY)],
        [Paragraph("ACUTE", BODY_BOLD), Paragraph("Ergot Alkaloids", BODY), Paragraph("Ergotamine, Dihydroergotamine (DHE)", BODY), Paragraph("Vasoconstriction via α+5-HT agonism", BODY)],
        [Paragraph("ACUTE", BODY_BOLD), Paragraph("Anti-emetics", BODY), Paragraph("Metoclopramide, Prochlorperazine, Ondansetron", BODY), Paragraph("Reduce nausea; improve absorption of analgesics", BODY)],
        [Paragraph("ACUTE", BODY_BOLD), Paragraph("Gepants (new)", BODY), Paragraph("Rimegepant, Ubrogepant, Atogepant", BODY), Paragraph("CGRP receptor antagonists - safe in CVD", BODY)],
        [Paragraph("PREVENTIVE\n(Prophylaxis)", BODY_BOLD), Paragraph("Beta Blockers (DOC)", BODY), Paragraph("Propranolol, Metoprolol, Timolol", BODY), Paragraph("Stabilize neuronal membranes", BODY)],
        [Paragraph("PREVENTIVE", BODY_BOLD), Paragraph("Anticonvulsants", BODY), Paragraph("Topiramate (preferred), Valproate, Gabapentin", BODY), Paragraph("↓cortical excitability", BODY)],
        [Paragraph("PREVENTIVE", BODY_BOLD), Paragraph("TCAs", BODY), Paragraph("Amitriptyline (most used)", BODY), Paragraph("Inhibit 5-HT/NE reuptake; also anticholinergic", BODY)],
        [Paragraph("PREVENTIVE", BODY_BOLD), Paragraph("Ca²⁺ Channel Blockers", BODY), Paragraph("Flunarizine, Verapamil (cluster HA)", BODY), Paragraph("Block CSD, vasodilation", BODY)],
        [Paragraph("PREVENTIVE", BODY_BOLD), Paragraph("Anti-CGRP MAbs", BODY), Paragraph("Erenumab, Fremanezumab, Galcanezumab", BODY), Paragraph("Monthly SC injection; bind CGRP ligand/receptor", BODY)],
        [Paragraph("PREVENTIVE", BODY_BOLD), Paragraph("Botulinum Toxin A", BODY), Paragraph("OnabotulinumtoxinA (Botox)", BODY), Paragraph("Chronic migraine only; every 12 weeks", BODY)],
    ]
    mtt = Table(migraine_tx, colWidths=[2.5*cm, 4*cm, 4.5*cm, 5.5*cm])
    mtt.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), HexColor("#880E4F")),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, HexColor("#FCE4EC")]),
        ("GRID", (0,0), (-1,-1), 0.4, HexColor("#F48FB1")),
        ("FONTSIZE", (0,0), (-1,-1), 8),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 22),
        ("SPAN", (0,1), (0,5)),  # Acute spans
    ]))
    story.append(mtt)
    story.append(sp(6))
    story.append(Paragraph("<b>★ EXAM TIP:</b> Propranolol = DOC for migraine prevention. Sumatriptan = DOC for acute moderate-severe migraine. Topiramate = preferred anticonvulsant for prevention (weight loss as SE).", EXAM_TIP))
    story.append(Paragraph("<b>★ EXAM TIP:</b> Ergotamine is CONTRAINDICATED in: pregnancy, vascular disease, liver/kidney disease, sepsis. It causes ergotism.", EXAM_TIP))
    story.append(Paragraph("<b>★ EXAM TIP:</b> Anti-CGRP monoclonal antibodies (erenumab) are new class - first to target migraine pathophysiology directly.", EXAM_TIP))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════
    # SECTION 7: QUICK REFERENCE & EXAM TIPS
    # ══════════════════════════════════════════════════════════════
    story.append(SectionHeader("EXAM QUICK REFERENCE", C_NAVY, "High-Yield MCQ Facts | Key Comparisons"))
    story.append(sp(6))

    story.append(Paragraph("<b>DOC (Drug of Choice) Summary</b>", H3))
    doc_data = [
        [Paragraph("<b>Condition</b>", TABLE_HDR), Paragraph("<b>Drug of Choice</b>", TABLE_HDR), Paragraph("<b>Drug Class</b>", TABLE_HDR)],
        [Paragraph("Anaphylaxis", BODY_BOLD), Paragraph("Epinephrine (IM)", BODY), Paragraph("Non-selective adrenergic agonist", BODY)],
        [Paragraph("Myasthenia Gravis", BODY_BOLD), Paragraph("Pyridostigmine", BODY), Paragraph("Reversible AChE inhibitor", BODY)],
        [Paragraph("Glaucoma (acute)", BODY_BOLD), Paragraph("Pilocarpine", BODY), Paragraph("Muscarinic agonist (M3)", BODY)],
        [Paragraph("Organophosphate poisoning", BODY_BOLD), Paragraph("Atropine + Pralidoxime", BODY), Paragraph("Muscarinic antagonist + AChE reactivator", BODY)],
        [Paragraph("Acute migraine (mod-severe)", BODY_BOLD), Paragraph("Sumatriptan", BODY), Paragraph("5-HT1B/1D agonist (Triptan)", BODY)],
        [Paragraph("Migraine prevention", BODY_BOLD), Paragraph("Propranolol", BODY), Paragraph("Non-selective β blocker", BODY)],
        [Paragraph("Allergic rhinitis (preferred)", BODY_BOLD), Paragraph("Cetirizine / Fexofenadine", BODY), Paragraph("2nd generation H1 antihistamine", BODY)],
        [Paragraph("Motion sickness", BODY_BOLD), Paragraph("Scopolamine (patch)", BODY), Paragraph("Anticholinergic (M1 blocker)", BODY)],
        [Paragraph("Bronchospasm in COPD", BODY_BOLD), Paragraph("Ipratropium / Tiotropium", BODY), Paragraph("Anticholinergic (M3 blocker, inhaled)", BODY)],
        [Paragraph("Asthma (acute)", BODY_BOLD), Paragraph("Salbutamol (Albuterol)", BODY), Paragraph("Selective β2 agonist", BODY)],
        [Paragraph("Septic shock", BODY_BOLD), Paragraph("Norepinephrine", BODY), Paragraph("α1, α2, β1 adrenergic agonist", BODY)],
        [Paragraph("Depression (1st line)", BODY_BOLD), Paragraph("SSRIs (e.g. Fluoxetine)", BODY), Paragraph("Serotonin reuptake inhibitor", BODY)],
        [Paragraph("Chemotherapy-induced nausea", BODY_BOLD), Paragraph("Ondansetron", BODY), Paragraph("5-HT3 antagonist", BODY)],
        [Paragraph("BPH (enlarged prostate)", BODY_BOLD), Paragraph("Tamsulosin", BODY), Paragraph("Selective α1A blocker", BODY)],
    ]
    doct = Table(doc_data, colWidths=[5*cm, 5*cm, 6.5*cm])
    doct.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_NAVY),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_LIGHTBLUE]),
        ("GRID", (0,0), (-1,-1), 0.4, HexColor("#BBDEFB")),
        ("FONTSIZE", (0,0), (-1,-1), 8.5),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 16),
    ]))
    story.append(doct)
    story.append(sp(8))

    story.append(Paragraph("<b>Critical Comparisons (High-Yield for MCQs)</b>", H3))
    compare = [
        [Paragraph("<b>Topic</b>", TABLE_HDR), Paragraph("<b>Drug A</b>", TABLE_HDR), Paragraph("<b>Drug B</b>", TABLE_HDR), Paragraph("<b>Key Difference</b>", TABLE_HDR)],
        [Paragraph("AChE Inhibitors", BODY_BOLD), Paragraph("Neostigmine", BODY), Paragraph("Physostigmine", BODY), Paragraph("Neostigmine: No BBB penetration. Physostigmine: Crosses BBB (CNS use)", BODY)],
        [Paragraph("Beta Blockers", BODY_BOLD), Paragraph("Propranolol", BODY), Paragraph("Atenolol/Metoprolol", BODY), Paragraph("Propranolol: non-selective (avoid in asthma). Atenolol: β1 selective, safer in asthma", BODY)],
        [Paragraph("Antihistamines", BODY_BOLD), Paragraph("Diphenhydramine (1st)", BODY), Paragraph("Fexofenadine (2nd)", BODY), Paragraph("1st gen: sedating, anticholinergic; 2nd gen: non-sedating, preferred in daytime", BODY)],
        [Paragraph("Triptans vs Ergots", BODY_BOLD), Paragraph("Sumatriptan", BODY), Paragraph("Ergotamine", BODY), Paragraph("Triptans: selective 5-HT1B/1D, fewer SE. Ergots: non-selective, more SE, more contraindications", BODY)],
        [Paragraph("Cholinomimetics", BODY_BOLD), Paragraph("Direct (Pilocarpine)", BODY), Paragraph("Indirect (Neostigmine)", BODY), Paragraph("Direct: bind receptor. Indirect: inhibit AChE to increase ACh availability", BODY)],
        [Paragraph("SSRIs vs SNRIs", BODY_BOLD), Paragraph("Fluoxetine (SSRI)", BODY), Paragraph("Venlafaxine (SNRI)", BODY), Paragraph("SSRIs: only 5-HT reuptake. SNRIs: 5-HT + NE reuptake; better for pain syndromes", BODY)],
        [Paragraph("α1 vs α2", BODY_BOLD), Paragraph("Phenylephrine (α1)", BODY), Paragraph("Clonidine (α2)", BODY), Paragraph("α1 agonist: vasoconstriction, ↑BP. α2 agonist: ↓NE release, ↓BP (central action)", BODY)],
    ]
    ct2 = Table(compare, colWidths=[3*cm, 3*cm, 3.5*cm, 7*cm])
    ct2.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_NAVY),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_LIGHTBLUE]),
        ("GRID", (0,0), (-1,-1), 0.4, HexColor("#BBDEFB")),
        ("FONTSIZE", (0,0), (-1,-1), 8),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 22),
    ]))
    story.append(ct2)
    story.append(PageBreak())

    # ── CONTRAINDICATIONS TABLE ──
    story.append(SectionHeader("CONTRAINDICATIONS & ADVERSE EFFECTS", C_RED, "High-Risk Combinations | Must-Know Safety Profiles"))
    story.append(sp(6))
    ci_data = [
        [Paragraph("<b>Drug/Class</b>", TABLE_HDR), Paragraph("<b>Contraindications</b>", TABLE_HDR), Paragraph("<b>Notable Adverse Effects</b>", TABLE_HDR)],
        [Paragraph("Non-selective β blockers\n(Propranolol)", BODY_BOLD), Paragraph("Asthma/COPD, AV block, Decompensated HF, Prinzmetal angina, IDDM", BODY), Paragraph("Bradycardia, Hypotension, Fatigue, Bronchoconstriction, Masks hypoglycemia", BODY)],
        [Paragraph("Anticholinergics\n(Atropine, etc.)", BODY_BOLD), Paragraph("Angle-closure glaucoma, BPH, Paralytic ileus, Tachycardia, Pyloric stenosis", BODY), Paragraph("Dry mouth, Urinary retention, Constipation, Confusion (elderly), Hyperthermia", BODY)],
        [Paragraph("SSRIs", BODY_BOLD), Paragraph("MAOIs (within 14 days), Linezolid (serotonin syndrome risk)", BODY), Paragraph("GI upset, Sexual dysfunction, Serotonin syndrome, SIADH, Bleeding risk (↓platelet)", BODY)],
        [Paragraph("Triptans", BODY_BOLD), Paragraph("IHD, Uncontrolled HTN, Hemiplegic/basilar migraine, Pregnancy (caution)", BODY), Paragraph("Flushing, Chest tightness, Coronary vasospasm, Serotonin syndrome (with SSRIs)", BODY)],
        [Paragraph("Ergot Alkaloids", BODY_BOLD), Paragraph("Pregnancy, Peripheral vascular disease, Hypertension, Liver/kidney disease, Sepsis", BODY), Paragraph("Ergotism (gangrene), Vasospasm, Nausea/vomiting", BODY)],
        [Paragraph("1st Gen Antihistamines", BODY_BOLD), Paragraph("Glaucoma (narrow angle), BPH, Elderly patients (Beers list), MAOIs", BODY), Paragraph("Sedation, Anticholinergic effects, Paradoxical excitation in children", BODY)],
        [Paragraph("Organophosphates\n(Cholinergic excess)", BODY_BOLD), Paragraph("Treatment: Atropine + Pralidoxime. Avoid succinylcholine!", BODY), Paragraph("SLUDGE BBB crisis: Bradycardia, Miosis, Salivation, Diarrhea, Bronchospasm", BODY)],
    ]
    cit = Table(ci_data, colWidths=[3.5*cm, 7*cm, 6*cm])
    cit.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_RED),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_RED_LT]),
        ("GRID", (0,0), (-1,-1), 0.4, HexColor("#EF9A9A")),
        ("FONTSIZE", (0,0), (-1,-1), 8),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 28),
    ]))
    story.append(cit)
    story.append(sp(8))

    # ── MNEMONICS BOX ──
    story.append(Paragraph("<b>Key Mnemonics for Exam</b>", H3))
    mnemonics = [
        [Paragraph("<b>Mnemonic</b>", TABLE_HDR), Paragraph("<b>Stands for</b>", TABLE_HDR), Paragraph("<b>Relevance</b>", TABLE_HDR)],
        [Paragraph("SLUDGE", BODY_BOLD), Paragraph("Salivation, Lacrimation, Urination, Defecation, GI cramps, Emesis", BODY), Paragraph("Cholinergic toxicity signs (OP poisoning, excess AChE inhibition)", BODY)],
        [Paragraph("DUMBELS", BODY_BOLD), Paragraph("Defecation, Urination, Miosis, Bradycardia, Emesis, Lacrimation, Salivation", BODY), Paragraph("Another mnemonic for organophosphate/cholinergic crisis", BODY)],
        [Paragraph("Dry as Bone\n(6 signs)", BODY_BOLD), Paragraph("Dry, Red, Hot, Blind, Mad, Full (as Flask)", BODY), Paragraph("Anticholinergic toxidrome signs", BODY)],
        [Paragraph("MAST cells", BODY_BOLD), Paragraph("Main site for histamine storage", BODY), Paragraph("Released in allergy, trauma, complement activation", BODY)],
        [Paragraph("Triple-S for SSRIs", BODY_BOLD), Paragraph("Safety, Selectivity, Second-line→1st line", BODY), Paragraph("SSRIs replaced TCAs as 1st-line antidepressants", BODY)],
    ]
    mnt = Table(mnemonics, colWidths=[3.5*cm, 7*cm, 6*cm])
    mnt.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), C_TEAL),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_TEAL_LT, C_WHITE]),
        ("GRID", (0,0), (-1,-1), 0.4, C_TEAL),
        ("FONTSIZE", (0,0), (-1,-1), 8.5),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ROWHEIGHT", (0,0), (-1,-1), 22),
    ]))
    story.append(mnt)
    story.append(sp(8))

    # FINAL SUMMARY FLOWCHART
    story.append(Paragraph("<b>Module Summary - Drug Classification Overview</b>", H3))
    summary_steps = [
        ("ANS DRUGS - MODULE 4.1 CLASSIFICATION OVERVIEW", C_NAVY),
        ("CHOLINERGIC (4.1.1): Pilocarpine, Neostigmine, Physostigmine | Glaucoma, Myasthenia Gravis, OP poisoning", C_TEAL),
        ("ANTICHOLINERGIC (4.1.1): Atropine, Scopolamine, Ipratropium | Bradycardia, Motion sickness, COPD", C_ORANGE),
        ("ADRENERGIC (4.1.2): Epinephrine, Salbutamol, Dopamine | Anaphylaxis, Shock, Asthma", C_RED),
        ("ANTIADRENERGIC (4.1.2): Propranolol, Metoprolol, Prazosin | HTN, Angina, HF, Arrhythmias", HexColor("#AD1457")),
        ("SEROTONERGIC (4.1.3): Fluoxetine (SSRI), Sumatriptan (triptan), Ondansetron | Depression, Migraine, N&V", C_PURPLE),
        ("HISTAMINE/ANTIHISTAMINIC (4.1.4): Diphenhydramine, Cetirizine, Ranitidine | Allergy, GERD, Urticaria", C_YELLOW),
        ("MIGRAINE: Acute = Triptans + NSAIDs | Prevention = Propranolol + Topiramate + Anti-CGRP", HexColor("#880E4F")),
    ]
    story.append(DiagramFlowchart(summary_steps, width=W - 3.6*cm, arrow=False))

    # ── Build the PDF ──
    doc.build(story)
    print(f"PDF generated: {output_path}")


if __name__ == "__main__":
    out = "/home/daytona/workspace/ans-autacoids-notes/ANS_Autacoids_Notes.pdf"
    build_pdf(out)
Your credits are exhausted. You can purchase a top-up or subscribe to a plan to continue using Orris. If you're already subscribed, your daily credits will reset tomorrow.

Prepare notes please

Your credits are exhausted. You can purchase a top-up or subscribe to a plan to continue using Orris. If you're already subscribed, your daily credits will reset tomorrow.

Generate the PDF notes from the Python script I prepared

Your credits are exhausted. You can purchase a top-up or subscribe to a plan to continue using Orris. If you're already subscribed, your daily credits will reset tomorrow.
This is a shared conversation. Sign in to Orris to start your own chat.