Make a detailed presentation on anashthesia

Asking for Preferences
Reading File
Reading File
Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Running Command

ls -la /home/daytona/workspace/ 2>/dev/null || mkdir -p /home/daytona/workspace

Running Command

mkdir -p /home/daytona/workspace/anesthesia-pdf && ls /home/daytona/workspace/anesthesia-pdf

Writing File

~/anesthesia-pdf/build_presentation.py

#!/usr/bin/env python3
"""
Anesthesia Presentation PDF Builder
For medical students - intermediate level
"""

from reportlab.lib.pagesizes import A4
from reportlab.lib.units import cm, mm
from reportlab.lib.colors import (
    HexColor, white, black, Color
)
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    PageBreak, HRFlowable, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT, TA_JUSTIFY
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate
from reportlab.lib import colors
import io

# ── Color Palette ──────────────────────────────────────────────────────────────
DEEP_NAVY    = HexColor("#0A1628")   # dominant dark background
MID_BLUE     = HexColor("#1B3A6B")   # section headers
TEAL_ACC     = HexColor("#00B4D8")   # accent / highlights
LIGHT_TEAL   = HexColor("#90E0EF")   # subheading tint
PALE_BG      = HexColor("#F0F8FF")   # content card background
WARM_GRAY    = HexColor("#E8ECF0")   # table alternating row
TEXT_DARK    = HexColor("#1A1A2E")   # body text
TEXT_MED     = HexColor("#2D3748")   # secondary body
GOLD_ACC     = HexColor("#FFB700")   # key callouts
RED_ACC      = HexColor("#E63946")   # warnings
GREEN_ACC    = HexColor("#2D9B5B")   # positive/ok

W, H = A4  # 595.28 x 841.89 pts

# ── Styles ─────────────────────────────────────────────────────────────────────
def make_styles():
    s = {}

    # Cover title
    s["cover_title"] = ParagraphStyle(
        "cover_title",
        fontName="Helvetica-Bold",
        fontSize=46,
        leading=54,
        textColor=white,
        alignment=TA_CENTER,
        spaceAfter=10
    )
    s["cover_subtitle"] = ParagraphStyle(
        "cover_subtitle",
        fontName="Helvetica",
        fontSize=18,
        leading=24,
        textColor=LIGHT_TEAL,
        alignment=TA_CENTER,
        spaceAfter=6
    )
    s["cover_tag"] = ParagraphStyle(
        "cover_tag",
        fontName="Helvetica",
        fontSize=13,
        leading=18,
        textColor=HexColor("#AECBEB"),
        alignment=TA_CENTER
    )

    # Section header (full-width colored bar)
    s["section_heading"] = ParagraphStyle(
        "section_heading",
        fontName="Helvetica-Bold",
        fontSize=22,
        leading=28,
        textColor=white,
        alignment=TA_LEFT,
        spaceBefore=0,
        spaceAfter=0,
        leftIndent=0
    )

    # Slide title within a section
    s["slide_title"] = ParagraphStyle(
        "slide_title",
        fontName="Helvetica-Bold",
        fontSize=17,
        leading=22,
        textColor=MID_BLUE,
        spaceBefore=10,
        spaceAfter=6
    )

    # Body text
    s["body"] = ParagraphStyle(
        "body",
        fontName="Helvetica",
        fontSize=11,
        leading=16,
        textColor=TEXT_DARK,
        spaceBefore=3,
        spaceAfter=3,
        alignment=TA_JUSTIFY
    )
    s["body_small"] = ParagraphStyle(
        "body_small",
        fontName="Helvetica",
        fontSize=10,
        leading=14,
        textColor=TEXT_MED,
        spaceBefore=2,
        spaceAfter=2,
        alignment=TA_JUSTIFY
    )

    # Bullet
    s["bullet"] = ParagraphStyle(
        "bullet",
        fontName="Helvetica",
        fontSize=11,
        leading=17,
        textColor=TEXT_DARK,
        bulletIndent=12,
        leftIndent=24,
        spaceBefore=2,
        spaceAfter=2
    )
    s["bullet_bold"] = ParagraphStyle(
        "bullet_bold",
        fontName="Helvetica-Bold",
        fontSize=11,
        leading=17,
        textColor=MID_BLUE,
        bulletIndent=12,
        leftIndent=24,
        spaceBefore=2,
        spaceAfter=2
    )
    s["sub_bullet"] = ParagraphStyle(
        "sub_bullet",
        fontName="Helvetica",
        fontSize=10,
        leading=15,
        textColor=TEXT_MED,
        bulletIndent=30,
        leftIndent=48,
        spaceBefore=1,
        spaceAfter=1
    )

    # Callout box label
    s["callout_title"] = ParagraphStyle(
        "callout_title",
        fontName="Helvetica-Bold",
        fontSize=11,
        leading=15,
        textColor=DEEP_NAVY,
        spaceBefore=4,
        spaceAfter=2
    )
    s["callout_body"] = ParagraphStyle(
        "callout_body",
        fontName="Helvetica",
        fontSize=10,
        leading=14,
        textColor=TEXT_DARK,
        spaceBefore=1,
        spaceAfter=1
    )

    # Table header
    s["table_header"] = ParagraphStyle(
        "table_header",
        fontName="Helvetica-Bold",
        fontSize=10,
        leading=13,
        textColor=white,
        alignment=TA_CENTER
    )
    s["table_cell"] = ParagraphStyle(
        "table_cell",
        fontName="Helvetica",
        fontSize=10,
        leading=13,
        textColor=TEXT_DARK,
        alignment=TA_LEFT
    )
    s["table_cell_center"] = ParagraphStyle(
        "table_cell_center",
        fontName="Helvetica",
        fontSize=10,
        leading=13,
        textColor=TEXT_DARK,
        alignment=TA_CENTER
    )

    # Page number
    s["page_num"] = ParagraphStyle(
        "page_num",
        fontName="Helvetica",
        fontSize=9,
        textColor=HexColor("#888888"),
        alignment=TA_CENTER
    )

    # Key number / stat
    s["big_stat"] = ParagraphStyle(
        "big_stat",
        fontName="Helvetica-Bold",
        fontSize=30,
        leading=36,
        textColor=TEAL_ACC,
        alignment=TA_CENTER
    )
    s["stat_label"] = ParagraphStyle(
        "stat_label",
        fontName="Helvetica",
        fontSize=10,
        leading=14,
        textColor=TEXT_MED,
        alignment=TA_CENTER
    )

    # ToC
    s["toc_title"] = ParagraphStyle(
        "toc_title",
        fontName="Helvetica-Bold",
        fontSize=14,
        leading=18,
        textColor=MID_BLUE,
        spaceBefore=4,
        spaceAfter=2
    )
    s["toc_item"] = ParagraphStyle(
        "toc_item",
        fontName="Helvetica",
        fontSize=11,
        leading=17,
        textColor=TEXT_DARK,
        leftIndent=20
    )

    return s


# ── Helper Builders ─────────────────────────────────────────────────────────────

def section_banner(title, color=None, story=None):
    """Full-width colored section banner."""
    if color is None:
        color = MID_BLUE
    t = Table(
        [[Paragraph(title, make_styles()["section_heading"])]],
        colWidths=[W - 4*cm]
    )
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), color),
        ("TOPPADDING",    (0,0), (-1,-1), 10),
        ("BOTTOMPADDING", (0,0), (-1,-1), 10),
        ("LEFTPADDING",   (0,0), (-1,-1), 16),
        ("RIGHTPADDING",  (0,0), (-1,-1), 16),
        ("ROUNDEDCORNERS", [6]),
    ]))
    if story is not None:
        story.append(t)
        story.append(Spacer(1, 12))
    return t


def bullet_item(text, st, bold=False):
    key = "bullet_bold" if bold else "bullet"
    return Paragraph(f"<bullet>\u2022</bullet>{text}", st[key])


def sub_bullet_item(text, st):
    return Paragraph(f"<bullet>\u2013</bullet>{text}", st["sub_bullet"])


def callout_box(title, items, color, st, story):
    """Colored callout box with title + bullet list."""
    rows = [[Paragraph(f"<b>{title}</b>", st["callout_title"])]]
    for it in items:
        rows.append([Paragraph(f"\u2022  {it}", st["callout_body"])])
    t = Table(rows, colWidths=[(W - 4*cm)])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), color),
        ("TOPPADDING",    (0,0), (-1,-1), 6),
        ("BOTTOMPADDING", (0,0), (-1,-1), 6),
        ("LEFTPADDING",   (0,0), (-1,-1), 14),
        ("RIGHTPADDING",  (0,0), (-1,-1), 14),
        ("ROUNDEDCORNERS", [5]),
    ]))
    story.append(t)
    story.append(Spacer(1, 10))


def two_col_table(headers, rows, st, story, col_widths=None):
    """Generic two-or-more column table with styled header."""
    if col_widths is None:
        usable = W - 4*cm
        col_widths = [usable / len(headers)] * len(headers)

    h_row = [Paragraph(h, st["table_header"]) for h in headers]
    data = [h_row]
    for i, row in enumerate(rows):
        data.append([Paragraph(str(cell), st["table_cell"]) for cell in row])

    t = Table(data, colWidths=col_widths, repeatRows=1)
    row_styles = [
        ("BACKGROUND",    (0,0), (-1,0), DEEP_NAVY),
        ("TEXTCOLOR",     (0,0), (-1,0), white),
        ("FONTNAME",      (0,0), (-1,0), "Helvetica-Bold"),
        ("ROWBACKGROUNDS",(0,1), (-1,-1), [white, WARM_GRAY]),
        ("GRID",          (0,0), (-1,-1), 0.4, HexColor("#C0CAD8")),
        ("TOPPADDING",    (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING",   (0,0), (-1,-1), 8),
        ("RIGHTPADDING",  (0,0), (-1,-1), 8),
        ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ]
    t.setStyle(TableStyle(row_styles))
    story.append(t)
    story.append(Spacer(1, 12))


def divider(story, color=TEAL_ACC):
    story.append(HRFlowable(width="100%", thickness=1.5, color=color, spaceAfter=8, spaceBefore=4))


# ── COVER PAGE ─────────────────────────────────────────────────────────────────

def build_cover(story, st):
    # Dark background block
    cover_data = [[
        Paragraph("ANAESTHESIA", st["cover_title"]),
    ]]
    cover_table = Table(cover_data, colWidths=[W - 4*cm])
    cover_table.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), DEEP_NAVY),
        ("TOPPADDING",    (0,0), (-1,-1), 60),
        ("BOTTOMPADDING", (0,0), (-1,-1), 20),
        ("LEFTPADDING",   (0,0), (-1,-1), 20),
        ("RIGHTPADDING",  (0,0), (-1,-1), 20),
        ("ALIGN",         (0,0), (-1,-1), "CENTER"),
    ]))
    story.append(cover_table)

    # Subtitle band
    sub_data = [[Paragraph("Principles, Types, Drugs &amp; Clinical Practice", st["cover_subtitle"])]]
    sub_table = Table(sub_data, colWidths=[W - 4*cm])
    sub_table.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), TEAL_ACC),
        ("TOPPADDING",    (0,0), (-1,-1), 14),
        ("BOTTOMPADDING", (0,0), (-1,-1), 14),
        ("LEFTPADDING",   (0,0), (-1,-1), 20),
        ("RIGHTPADDING",  (0,0), (-1,-1), 20),
    ]))
    story.append(sub_table)

    # Tag line
    tag_data = [[Paragraph(
        "A comprehensive presentation for medical students<br/>"
        "Based on Miller's Anesthesia (10e) &amp; Morgan &amp; Mikhail's Clinical Anesthesiology (7e)",
        st["cover_tag"]
    )]]
    tag_table = Table(tag_data, colWidths=[W - 4*cm])
    tag_table.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), MID_BLUE),
        ("TOPPADDING",    (0,0), (-1,-1), 20),
        ("BOTTOMPADDING", (0,0), (-1,-1), 30),
        ("LEFTPADDING",   (0,0), (-1,-1), 20),
        ("RIGHTPADDING",  (0,0), (-1,-1), 20),
    ]))
    story.append(tag_table)
    story.append(Spacer(1, 20))

    # Stats strip
    stats = [
        ("1842", "Year ether first used surgically"),
        ("3", "Pillars of anesthesia"),
        ("4", "Types of anesthesia"),
        ("~230M", "Surgeries/year under anesthesia"),
    ]
    cells = []
    for num, lbl in stats:
        cell_content = [
            [Paragraph(num, st["big_stat"])],
            [Paragraph(lbl, st["stat_label"])],
        ]
        inner = Table(cell_content, colWidths=[(W - 4*cm) / 4 - 6])
        inner.setStyle(TableStyle([
            ("BACKGROUND", (0,0), (-1,-1), PALE_BG),
            ("TOPPADDING",    (0,0), (-1,-1), 10),
            ("BOTTOMPADDING", (0,0), (-1,-1), 10),
            ("LEFTPADDING",   (0,0), (-1,-1), 4),
            ("RIGHTPADDING",  (0,0), (-1,-1), 4),
            ("ROUNDEDCORNERS", [4]),
        ]))
        cells.append(inner)

    stat_table = Table([cells], colWidths=[(W - 4*cm) / 4] * 4)
    stat_table.setStyle(TableStyle([
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("LEFTPADDING",   (0,0), (-1,-1), 3),
        ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ]))
    story.append(stat_table)
    story.append(PageBreak())


# ── TABLE OF CONTENTS ──────────────────────────────────────────────────────────

def build_toc(story, st):
    section_banner("Table of Contents", MID_BLUE, story)
    toc_items = [
        ("01", "History of Anaesthesia"),
        ("02", "Definition & Core Concepts"),
        ("03", "Components of Anaesthesia (The Triad)"),
        ("04", "Types of Anaesthesia"),
        ("05", "Pre-operative Assessment (ASA Classification)"),
        ("06", "Inhalational Anaesthetic Agents"),
        ("07", "Intravenous Anaesthetic Agents"),
        ("08", "Opioids in Anaesthesia"),
        ("09", "Muscle Relaxants (Neuromuscular Blocking Agents)"),
        ("10", "Local Anaesthetics"),
        ("11", "Regional & Neuraxial Anaesthesia"),
        ("12", "Induction, Maintenance & Emergence"),
        ("13", "Airway Management"),
        ("14", "Intraoperative Monitoring"),
        ("15", "Complications & Awareness"),
        ("16", "Special Populations"),
        ("17", "Post-Anaesthesia Care (PACU)"),
        ("18", "Key Summary & Clinical Pearls"),
    ]
    data = []
    for i in range(0, len(toc_items), 2):
        row = []
        for j in [0, 1]:
            if i+j < len(toc_items):
                num, title = toc_items[i+j]
                row.append(Paragraph(
                    f'<font color="#00B4D8"><b>{num}</b></font>  {title}',
                    st["toc_item"]
                ))
            else:
                row.append(Paragraph("", st["toc_item"]))
        data.append(row)

    t = Table(data, colWidths=[(W - 4*cm)/2, (W - 4*cm)/2])
    t.setStyle(TableStyle([
        ("ROWBACKGROUNDS", (0,0), (-1,-1), [PALE_BG, white]),
        ("TOPPADDING",    (0,0), (-1,-1), 7),
        ("BOTTOMPADDING", (0,0), (-1,-1), 7),
        ("LEFTPADDING",   (0,0), (-1,-1), 12),
        ("RIGHTPADDING",  (0,0), (-1,-1), 12),
        ("LINEBELOW",     (0,0), (-1,-1), 0.3, HexColor("#D0D8E4")),
    ]))
    story.append(t)
    story.append(PageBreak())


# ── SLIDE: HISTORY ─────────────────────────────────────────────────────────────

def slide_history(story, st):
    section_banner("01  |  History of Anaesthesia", MID_BLUE, story)
    story.append(Paragraph("From Ether to Modern Practice", st["slide_title"]))
    story.append(Paragraph(
        "The history of anaesthesia is one of medicine's most transformative stories, turning surgery "
        "from a brutal ordeal into a controlled, painless intervention.",
        st["body"]
    ))
    story.append(Spacer(1, 8))

    timeline = [
        ["Year", "Event", "Agent/Person"],
        ["1540", "Diethyl ether first synthesized", "Valerius Cordus"],
        ["1772", "Nitrous oxide produced", "Joseph Priestley"],
        ["1800", "Analgesic properties of N₂O noted", "Humphry Davy"],
        ["1842", "First surgical use of ether", "Crawford W. Long / William E. Clark"],
        ["Oct 16, 1846", "First PUBLIC demonstration of ether anaesthesia (Boston)", "W.T.G. Morton"],
        ["1847", "Chloroform introduced for labour pain", "Sir James Simpson"],
        ["1868", "Nitrous oxide given in 20% O₂", "Edmund Andrews"],
        ["1934", "Cyclopropane introduced", "—"],
        ["1951", "Halothane developed (released 1956)", "ICI"],
        ["1965", "Isoflurane developed (released 1981)", "—"],
        ["1992", "Desflurane released", "—"],
        ["1994", "Sevoflurane released in USA", "—"],
    ]
    two_col_table(timeline[0], timeline[1:], st, story,
                  col_widths=[2.2*cm, 8.5*cm, 4.3*cm])

    callout_box(
        "Key Quote (1846)",
        ['"Gentlemen, this is no humbug!" — Surgeon Henry Jacob Bigelow, after witnessing Morton\'s first public demonstration of ether anaesthesia at Massachusetts General Hospital.'],
        HexColor("#FFF3CD"), st, story
    )
    story.append(PageBreak())


# ── SLIDE: DEFINITION ─────────────────────────────────────────────────────────

def slide_definition(story, st):
    section_banner("02  |  Definition & Core Concepts", MID_BLUE, story)
    story.append(Paragraph("What is Anaesthesia?", st["slide_title"]))
    story.append(Paragraph(
        "The word <i>anaesthesia</i> derives from the Greek <b>an-</b> (without) + <b>aisthesis</b> "
        "(sensation). Modern anaesthesia is a medically induced, reversible state that allows surgical "
        "and procedural interventions to be performed safely and without pain.",
        st["body"]
    ))
    story.append(Spacer(1, 8))

    story.append(Paragraph("Core Objectives of Anaesthetic Management", st["slide_title"]))
    objectives = [
        ("<b>Analgesia</b> — Elimination of pain (somatic and visceral)",),
        ("<b>Amnesia</b> — Prevention of conscious recall of events",),
        ("<b>Muscle Relaxation</b> — Facilitation of surgical access and intubation",),
        ("<b>Unconsciousness / Hypnosis</b> — Reversible loss of awareness",),
        ("<b>Abolition of Autonomic Reflexes</b> — Blunting of stress responses (tachycardia, hypertension)",),
        ("<b>Haemodynamic Stability</b> — Maintenance of physiological homeostasis",),
    ]
    for obj in objectives:
        story.append(Paragraph(f"<bullet>\u2022</bullet>{obj[0]}", st["bullet"]))
    story.append(Spacer(1, 10))

    callout_box(
        "Balanced Anaesthesia",
        [
            "Using a single agent at high doses often causes excessive haemodynamic depression.",
            "\"Balanced anaesthesia\" combines multiple agents — opioids, inhalational agents, and muscle relaxants — to achieve each component selectively while minimising side effects.",
            "Source: Miller's Anesthesia, 10e, Chapter 22"
        ],
        HexColor("#E8F4FD"), st, story
    )
    story.append(PageBreak())


# ── SLIDE: THE TRIAD ───────────────────────────────────────────────────────────

def slide_triad(story, st):
    section_banner("03  |  Components of Anaesthesia — The Triad", TEAL_ACC, story)
    story.append(Paragraph("The Anaesthetic Triad", st["slide_title"]))
    story.append(Paragraph(
        "Three essential components must be achieved for safe general anaesthesia:",
        st["body"]
    ))
    story.append(Spacer(1, 8))

    triad_data = [
        [
            Paragraph("<b>HYPNOSIS</b>\n(Unconsciousness)", st["table_header"]),
            Paragraph("<b>ANALGESIA</b>\n(Pain Relief)", st["table_header"]),
            Paragraph("<b>MUSCLE RELAXATION</b>", st["table_header"]),
        ],
        [
            Paragraph(
                "• Propofol\n• Thiopental\n• Volatile agents\n• Benzodiazepines",
                st["table_cell"]
            ),
            Paragraph(
                "• Opioids (morphine, fentanyl)\n• Ketamine (NMDA block)\n• Regional techniques\n• NSAIDs",
                st["table_cell"]
            ),
            Paragraph(
                "• Succinylcholine (depolarising)\n• Rocuronium, Vecuronium (non-depolarising)\n• Volatile agents (partial)",
                st["table_cell"]
            ),
        ]
    ]
    t = Table(triad_data, colWidths=[(W - 4*cm)/3]*3)
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,0), MID_BLUE),
        ("BACKGROUND",    (0,1), (0,1), HexColor("#E8F4FD")),
        ("BACKGROUND",    (1,1), (1,1), HexColor("#FFF0F0")),
        ("BACKGROUND",    (2,1), (2,1), HexColor("#F0FFF0")),
        ("GRID",          (0,0), (-1,-1), 0.5, HexColor("#C0CAD8")),
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
        ("TOPPADDING",    (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("RIGHTPADDING",  (0,0), (-1,-1), 10),
    ]))
    story.append(t)
    story.append(Spacer(1, 14))

    story.append(Paragraph("MAC — Minimum Alveolar Concentration", st["slide_title"]))
    story.append(Paragraph(
        "MAC is the alveolar concentration of an inhaled anaesthetic (at 1 atm) that prevents movement "
        "in response to a standard surgical stimulus in 50% of patients. It is the standard measure "
        "of potency for volatile agents.",
        st["body"]
    ))
    mac_items = [
        "MAC is inversely related to lipid solubility (Meyer-Overton correlation)",
        "MAC is additive: combined agents sum their fractional MACs",
        "MAC-awake (~0.3–0.4 MAC): concentration at which 50% of patients open eyes on command",
        "MAC-BAR: concentration that blunts autonomic response to surgical incision",
        "MAC decreases with: age, hypothermia, pregnancy, opioids, sedatives",
        "MAC increases with: hyperthermia, chronic alcohol use, hypernatraemia",
    ]
    for item in mac_items:
        story.append(Paragraph(f"<bullet>\u2022</bullet>{item}", st["bullet"]))
    story.append(PageBreak())


# ── SLIDE: TYPES ───────────────────────────────────────────────────────────────

def slide_types(story, st):
    section_banner("04  |  Types of Anaesthesia", MID_BLUE, story)
    story.append(Spacer(1, 6))

    types = [
        (
            "GENERAL ANAESTHESIA",
            MID_BLUE,
            [
                "Produces complete unconsciousness, analgesia, and muscle relaxation",
                "Administered via inhalation (volatile agents) or IV (propofol, thiopental)",
                "Requires airway management: LMA, ETT, or supraglottic device",
                "Indicated for: major surgery, uncooperative patients, need for complete muscle relaxation",
                "Risk: aspiration, cardiovascular depression, PONV, malignant hyperthermia",
            ]
        ),
        (
            "REGIONAL ANAESTHESIA",
            HexColor("#1D6A8F"),
            [
                "Blocks sensory (and often motor) signals from a specific body region",
                "Patient remains conscious or lightly sedated",
                "Subtypes: spinal (intrathecal), epidural, combined spinal-epidural (CSE), peripheral nerve blocks",
                "Advantages: avoids airway manipulation, reduced opioid use, earlier mobilisation",
                "Risk: PDPH (post-dural puncture headache), haematoma, high block",
            ]
        ),
        (
            "LOCAL ANAESTHESIA",
            HexColor("#1A7A5E"),
            [
                "Infiltration or topical application of local anaesthetic agents",
                "Blocks Na⁺ channels → prevents depolarisation of nerve fibres",
                "Agents: lidocaine, bupivacaine, ropivacaine, prilocaine",
                "Used for minor procedures, suturing, dermatology, dental",
                "Risk: local anaesthetic systemic toxicity (LAST) if absorbed/injected IV",
            ]
        ),
        (
            "MONITORED ANAESTHESIA CARE (MAC / Sedation)",
            HexColor("#7B3A6D"),
            [
                "IV sedation with anxiolysis while patient maintains spontaneous ventilation",
                "Levels: minimal, moderate (conscious), deep sedation, general anaesthesia",
                "Agents: propofol, midazolam, ketamine, dexmedetomidine, fentanyl",
                "Used for: endoscopy, minor procedures, radiological interventions",
                "Risk: respiratory depression, loss of protective reflexes at deep levels",
            ]
        ),
    ]

    for title, color, points in types:
        header = Table([[Paragraph(title, st["section_heading"])]], colWidths=[W - 4*cm])
        header.setStyle(TableStyle([
            ("BACKGROUND",    (0,0), (-1,-1), color),
            ("TOPPADDING",    (0,0), (-1,-1), 8),
            ("BOTTOMPADDING", (0,0), (-1,-1), 8),
            ("LEFTPADDING",   (0,0), (-1,-1), 14),
            ("ROUNDEDCORNERS", [4]),
        ]))
        story.append(header)
        for pt in points:
            story.append(Paragraph(f"<bullet>\u2022</bullet>{pt}", st["bullet"]))
        story.append(Spacer(1, 10))
    story.append(PageBreak())


# ── SLIDE: PRE-OP ASSESSMENT ──────────────────────────────────────────────────

def slide_preop(story, st):
    section_banner("05  |  Pre-operative Assessment & ASA Classification", MID_BLUE, story)
    story.append(Paragraph(
        "A thorough pre-operative assessment is fundamental to safe anaesthetic management. "
        "It identifies risk factors, optimises comorbidities, and guides anaesthetic planning.",
        st["body"]
    ))
    story.append(Spacer(1, 8))

    story.append(Paragraph("Key Components of Pre-op Assessment", st["slide_title"]))
    preop_items = [
        "<b>History:</b> Previous anaesthetics (problems? reactions?), medications, allergies, fasting status",
        "<b>Examination:</b> Airway assessment (Mallampati, mouth opening, neck mobility), cardiovascular, respiratory",
        "<b>Investigations:</b> FBC, U&E, ECG, CXR, coagulation — guided by patient factors and surgery type",
        "<b>Fasting:</b> Clear fluids ≥2 h, solids/breast milk ≥4–6 h before induction ('2-4-6 rule')",
        "<b>Consent:</b> Discuss risks including PONV, sore throat, awareness, nerve injury",
    ]
    for it in preop_items:
        story.append(Paragraph(f"<bullet>\u2022</bullet>{it}", st["bullet"]))
    story.append(Spacer(1, 10))

    story.append(Paragraph("ASA Physical Status Classification", st["slide_title"]))
    asa_rows = [
        ["ASA I",   "Normal healthy patient",                        "Healthy, non-smoker, minimal EtOH"],
        ["ASA II",  "Mild systemic disease",                         "Mild asthma, well-controlled DM/HTN, obesity BMI 30–40"],
        ["ASA III", "Severe systemic disease",                        "Poorly controlled DM/HTN, COPD, morbid obesity (BMI>40), active hepatitis"],
        ["ASA IV",  "Severe systemic disease, constant threat to life","Recent MI (<3 months), severe valve disease, sepsis"],
        ["ASA V",   "Moribund — not expected to survive >24 h",      "Ruptured AAA, massive trauma, intracranial bleed with herniation"],
        ["ASA VI",  "Brain-dead, organ donor",                       "—"],
        ["E suffix", "Emergency surgery",                            "Added to any class (e.g. ASA IIE)"],
    ]
    two_col_table(
        ["Class", "Definition", "Examples"],
        asa_rows, st, story,
        col_widths=[1.8*cm, 6.5*cm, 6.7*cm]
    )
    story.append(PageBreak())


# ── SLIDE: INHALATIONAL AGENTS ────────────────────────────────────────────────

def slide_inhalational(story, st):
    section_banner("06  |  Inhalational Anaesthetic Agents", MID_BLUE, story)
    story.append(Paragraph(
        "Inhalational agents were the first general anaesthetics and remain a cornerstone "
        "of modern practice. They act primarily by enhancing inhibitory (GABA-A) and inhibiting "
        "excitatory (NMDA) neurotransmission.",
        st["body"]
    ))
    story.append(Spacer(1, 8))

    story.append(Paragraph("Pharmacology: Key Concepts", st["slide_title"]))
    for it in [
        "<b>Blood:Gas partition coefficient</b> — lower = faster induction/emergence (desflurane &lt; N₂O &lt; sevoflurane &lt; isoflurane)",
        "<b>MAC (Minimum Alveolar Concentration)</b> — inversely proportional to lipid solubility (potency marker)",
        "<b>Uptake</b> depends on: inspired concentration, alveolar ventilation, cardiac output, blood solubility",
        "<b>Biotransformation</b> — volatile agents metabolised to varying degrees; halothane (20%) &gt;&gt; sevoflurane (5%) &gt; isoflurane (0.2%) &gt; desflurane (0.02%)",
    ]:
        story.append(Paragraph(f"<bullet>\u2022</bullet>{it}", st["bullet"]))
    story.append(Spacer(1, 8))

    agents = [
        ["Agent",        "MAC (%)", "Blood:Gas", "Metabolism", "Key Features / Cautions"],
        ["Nitrous Oxide\n(N₂O)", "105",  "0.47",  "Minimal",    "Analgesic; needs O₂; expands air-filled cavities; diffusion hypoxia on discontinuation; B12 inhibition; not used alone"],
        ["Isoflurane",   "1.17",   "1.4",  "0.2%",     "Pungent — not suitable for gas induction; coronary vasodilator; cheap; respiratory depression"],
        ["Sevoflurane",  "2.05",   "0.65", "5%",       "Pleasant smell — ideal for gas induction; low pungency; degraded by CO₂ absorber (Compound A — renal toxicity theoretical); most widely used"],
        ["Desflurane",   "6.0",    "0.42", "0.02%",    "Fastest emergence; very pungent (airway irritant — cannot use for induction); requires heated vaporiser; sympathetic stimulation on rapid ↑"],
        ["Halothane",    "0.75",   "2.3",  "20%",      "Potent; hepatotoxic (halothane hepatitis); sensitises myocardium to catecholamines; largely abandoned in developed countries; still used in paediatrics in resource-limited settings"],
    ]
    two_col_table(
        agents[0], agents[1:], st, story,
        col_widths=[2.5*cm, 1.5*cm, 1.8*cm, 2.0*cm, 7.2*cm]
    )

    callout_box(
        "Clinical Pearl: Sevoflurane vs Desflurane",
        [
            "Sevoflurane is by far the most popular inhaled agent in developed countries — low pungency, suitable for gas induction, and low blood solubility for rapid titration.",
            "Desflurane offers the fastest emergence (nearly as fast as N₂O) but cannot be used for induction due to airway irritation.",
            "Source: Morgan & Mikhail's Clinical Anesthesiology, 7e, Chapter 1",
        ],
        HexColor("#E8F4FD"), st, story
    )
    story.append(PageBreak())


# ── SLIDE: IV AGENTS ──────────────────────────────────────────────────────────

def slide_iv_agents(story, st):
    section_banner("07  |  Intravenous Anaesthetic Agents", MID_BLUE, story)
    story.append(Paragraph(
        "IV agents are used for induction and total intravenous anaesthesia (TIVA). "
        "They are typically lipophilic, crossing the blood–brain barrier rapidly.",
        st["body"]
    ))
    story.append(Spacer(1, 8))

    iv_agents = [
        ["Agent",       "Mechanism",          "Dose",            "Onset/Duration",    "Key Points"],
        ["Propofol",    "GABA-A agonist",      "Induction: 1–2.5 mg/kg\nMaintenance: 25–150 mcg/kg/min",
         "Rapid / 3–8 min", "Most widely used induction agent; antiemetic; pain on injection; PRIS (prolonged infusion); hypotension; not analgesic"],
        ["Thiopental\n(Thiopentone)", "GABA-A agonist (barbiturate)",
         "3–6 mg/kg IV",   "Rapid / 5–10 min", "Rapid induction; cerebral protection; contraindicated in porphyria; cumulative with repeated doses; largely replaced by propofol"],
        ["Etomidate",   "GABA-A modulator",   "0.2–0.4 mg/kg",   "Rapid / 3–5 min",  "Minimal CVS depression → preferred in haemodynamic instability; adrenocortical suppression (avoid infusion); myoclonus; pain on injection; high PONV"],
        ["Ketamine",    "NMDA receptor antagonist", "IV: 1–2 mg/kg\nIM: 4–10 mg/kg",
         "Rapid / 10–15 min", "Dissociative anaesthesia; preserves airway reflexes; bronchodilator; raises HR/BP → good in haemodynamic compromise; emergence hallucinations (benzodiazepine pretreatment); neuroprotective"],
        ["Midazolam",   "GABA-A (BZD site)",  "0.01–0.1 mg/kg",  "2–3 min / 20–40 min","Anxiolysis, amnesia, anticonvulsant; not analgesic; reversal: flumazenil"],
        ["Dexmedetomidine", "α₂ agonist",     "0.5–1 mcg/kg load\nthen 0.2–0.7 mcg/kg/h",
         "Gradual / varies", "Sedation without respiratory depression; analgesic sparing; sympatholysis (bradycardia/hypotension); PONV↓"],
    ]
    two_col_table(
        iv_agents[0], iv_agents[1:], st, story,
        col_widths=[2.4*cm, 2.8*cm, 3.2*cm, 2.6*cm, 4.0*cm]
    )

    callout_box(
        "TIVA (Total Intravenous Anaesthesia)",
        [
            "Propofol + remifentanil infusion is the standard TIVA combination.",
            "Advantages: reduced PONV, avoids volatile agent pollution, rapid recovery.",
            "TCI (target-controlled infusion) systems use pharmacokinetic models to maintain target plasma/effect-site concentrations.",
        ],
        HexColor("#F0FFF0"), st, story
    )
    story.append(PageBreak())


# ── SLIDE: OPIOIDS ────────────────────────────────────────────────────────────

def slide_opioids(story, st):
    section_banner("08  |  Opioids in Anaesthesia", MID_BLUE, story)
    story.append(Paragraph(
        "Opioids are the primary analgesic component of balanced anaesthesia. They act on μ, κ, and δ "
        "receptors in the CNS and peripheral nervous system to inhibit pain transmission.",
        st["body"]
    ))
    story.append(Spacer(1, 8))

    opioids = [
        ["Drug",          "Route",  "Onset",      "Duration",   "Relative Potency", "Key Notes"],
        ["Morphine",      "IV/IM/SC","15–30 min",  "3–5 h",      "1×",               "Active metabolite M6G; histamine release; avoid in renal failure; useful for post-op analgesia"],
        ["Fentanyl",      "IV",     "1–2 min",    "30–60 min",  "100×",             "Most commonly used intra-operatively; epidural/intrathecal use; transdermal patch"],
        ["Sufentanil",    "IV",     "1–2 min",    "30–60 min",  "1000×",            "High-dose cardiac anaesthesia; epidural use in labour"],
        ["Alfentanil",    "IV",     "&lt;1 min",    "10–20 min",  "10–25×",           "Context-sensitive half-time; good for short procedures"],
        ["Remifentanil",  "IV infusion","1 min",  "3–5 min",    "100–200×",         "Hydrolysed by plasma esterases; ultra-short action; no accumulation; no post-op analgesia → plan ahead; ideal for TIVA; strong respiratory depressant"],
        ["Tramadol",      "IV/PO",  "15–30 min",  "4–6 h",      "0.1×",             "Weak μ agonist + SNRI; not for strong pain; PONV; serotonin syndrome risk"],
    ]
    two_col_table(
        opioids[0], opioids[1:], st, story,
        col_widths=[2.4*cm, 1.5*cm, 2.0*cm, 1.8*cm, 2.3*cm, 5.0*cm]
    )

    story.append(Paragraph("Side Effects of Opioids", st["slide_title"]))
    for it in [
        "Respiratory depression — dose-dependent; reversed by naloxone (0.1–0.4 mg IV in increments)",
        "Nausea and vomiting (stimulate chemoreceptor trigger zone)",
        "Sedation and cognitive impairment",
        "Pruritus (especially intrathecal/epidural)",
        "Constipation and ileus",
        "Urinary retention",
        "Bradycardia (especially fentanyl analogues)",
        "Tolerance and dependence with prolonged use",
    ]:
        story.append(Paragraph(f"<bullet>\u2022</bullet>{it}", st["bullet"]))
    story.append(PageBreak())


# ── SLIDE: MUSCLE RELAXANTS ───────────────────────────────────────────────────

def slide_nmba(story, st):
    section_banner("09  |  Muscle Relaxants (Neuromuscular Blocking Agents)", MID_BLUE, story)
    story.append(Paragraph(
        "Neuromuscular blocking agents (NMBAs) act at the nicotinic acetylcholine receptor (nAChR) "
        "at the neuromuscular junction. They facilitate intubation and provide surgical muscle relaxation.",
        st["body"]
    ))
    story.append(Spacer(1, 8))

    nmba_data = [
        ["Drug",           "Type",                 "Onset",     "Duration",   "Dose (Intubation)", "Notes"],
        ["Succinylcholine\n(Suxamethonium)", "Depolarising",   "30–60 s",   "5–10 min",    "1–1.5 mg/kg",    "Fastest onset → RSI; fasciculations; K⁺ rise (avoid in burns, denervation); malignant hyperthermia trigger; phase II block possible; no reversal"],
        ["Rocuronium",     "Non-depolarising\n(aminosteroid)", "60–90 s",   "30–45 min",   "0.6 mg/kg\n(RSI: 1.2 mg/kg)", "Fastest non-depolarising; reversed by sugammadex; modified RSI option"],
        ["Vecuronium",     "Non-depolarising\n(aminosteroid)", "2–3 min",   "25–40 min",   "0.1 mg/kg",      "Minimal CVS effects; hepatic elimination; active metabolite"],
        ["Atracurium",     "Non-depolarising\n(benzylisoquinolinium)", "2–3 min", "20–35 min","0.5 mg/kg",   "Hofmann elimination → safe in renal/hepatic failure; histamine release; laudanosine"],
        ["Cisatracurium",  "Non-depolarising\n(benzylisoquinolinium)", "2–3 min", "45–60 min","0.15 mg/kg",  "Isomer of atracurium; no histamine release; Hofmann elimination; preferred in ICU"],
        ["Mivacurium",     "Non-depolarising\n(benzylisoquinolinium)", "2–3 min", "12–20 min","0.15 mg/kg",  "Short-acting; hydrolysed by plasma cholinesterase; prolonged block if pseudocholinesterase deficiency"],
    ]
    two_col_table(
        nmba_data[0], nmba_data[1:], st, story,
        col_widths=[2.4*cm, 2.8*cm, 1.5*cm, 1.8*cm, 2.0*cm, 4.5*cm]
    )

    story.append(Paragraph("Reversal of Neuromuscular Blockade", st["slide_title"]))
    rev_items = [
        "<b>Neostigmine</b> (+ glycopyrrolate/atropine to prevent bradycardia): anticholinesterase; reverses non-depolarising blocks when T4:T1 ratio ≥0.1 (2 twitches on TOF)",
        "<b>Sugammadex</b>: modified γ-cyclodextrin; encapsulates rocuronium/vecuronium; reverses any depth of block; dose: 2–16 mg/kg; revolutionised RSI safety",
        "<b>TOF (Train-of-Four) monitoring</b>: 4 supramaximal stimuli at 2 Hz; adequate reversal: T4/T1 ratio ≥0.9",
    ]
    for it in rev_items:
        story.append(Paragraph(f"<bullet>\u2022</bullet>{it}", st["bullet"]))
    story.append(PageBreak())


# ── SLIDE: LOCAL ANAESTHETICS ─────────────────────────────────────────────────

def slide_local(story, st):
    section_banner("10  |  Local Anaesthetic Agents", MID_BLUE, story)
    story.append(Paragraph(
        "Local anaesthetics (LAs) reversibly block Na⁺ channels in the nerve axon membrane, "
        "preventing the generation and propagation of action potentials. They act preferentially "
        "on small, myelinated Aδ (pain/temperature) fibres before large motor fibres.",
        st["body"]
    ))
    story.append(Spacer(1, 8))

    la_data = [
        ["Drug",          "Class",   "Onset",    "Duration",    "Max Dose\n(plain)",  "Key Uses / Notes"],
        ["Lidocaine\n(Lignocaine)", "Amide", "Fast",   "1–2 h",       "3 mg/kg\n(7 mg/kg + epi)", "Most versatile; antiarrhythmic; topical; IV regional (Bier's block); also used for intubation (topical spray)"],
        ["Bupivacaine",   "Amide",   "Slow",     "4–8 h",       "2 mg/kg",            "Long duration; spinal/epidural; cardiotoxic (wide QRS, arrhythmia) if IV — treat with intralipid 20%; NOT for IV regional"],
        ["Ropivacaine",   "Amide",   "Moderate", "4–6 h",       "3 mg/kg",            "Less cardiotoxic than bupivacaine; greater motor-sensory differential (preferred in epidurals)"],
        ["Levobupivacaine","Amide",  "Slow",     "4–8 h",       "2.5 mg/kg",          "S-enantiomer of bupivacaine; less cardiotoxic; similar duration"],
        ["Prilocaine",    "Amide",   "Moderate", "2–3 h",       "6 mg/kg\n(8 mg/kg + epi)", "IV regional (Bier's block); methaemoglobinaemia at high doses"],
        ["Procaine",      "Ester",   "Moderate", "1 h",         "7 mg/kg",            "Spinal anaesthesia; metabolised by plasma cholinesterase; low toxicity"],
        ["Cocaine",       "Ester",   "Fast",     "1 h",         "3 mg/kg\n(topical only)", "Only LA with vasoconstriction; ENT topical use; controlled substance"],
    ]
    two_col_table(
        la_data[0], la_data[1:], st, story,
        col_widths=[2.4*cm, 1.4*cm, 1.8*cm, 1.5*cm, 2.0*cm, 6.0*cm]
    )

    callout_box(
        "LAST — Local Anaesthetic Systemic Toxicity",
        [
            "CNS: perioral tingling → tinnitus → visual disturbances → seizures → coma",
            "CVS: hypotension, bradycardia, ventricular arrhythmia, cardiac arrest",
            "Treatment: stop injection, 100% O₂, IV lipid emulsion (20%) 1.5 mL/kg bolus",
            "Prevention: aspirate before injection, incremental dosing, avoid IV bolus",
        ],
        HexColor("#FFE8E8"), st, story
    )
    story.append(PageBreak())


# ── SLIDE: REGIONAL / NEURAXIAL ───────────────────────────────────────────────

def slide_regional(story, st):
    section_banner("11  |  Regional & Neuraxial Anaesthesia", MID_BLUE, story)

    story.append(Paragraph("Spinal vs Epidural — Comparison", st["slide_title"]))
    comp = [
        ["Feature",            "Spinal (Intrathecal)",                    "Epidural"],
        ["Location",           "Subarachnoid space (CSF)",                 "Epidural space (fat + vessels)"],
        ["Needle",             "25–27G Whitacre/Quincke",                  "16–18G Tuohy"],
        ["LA Volume",          "Small (2–5 mL)",                           "Large (10–30 mL)"],
        ["Onset",              "Fast (2–5 min)",                           "Slower (15–20 min)"],
        ["Duration",           "Fixed (1.5–3 h; dose-dependent)",          "Titrable (catheter allows top-up)"],
        ["Block density",      "Dense motor + sensory",                    "Motor-sparing possible"],
        ["Common uses",        "Lower limb surgery, LSCS, prostatectomy",  "Labour analgesia, thoracic surgery, post-op pain"],
        ["Major risks",        "PDPH, hypotension, high block, cauda equina","PDPH (rare), epidural haematoma, infection, failed block"],
        ["PDPH treatment",     "Rest, hydration, caffeine, blood patch",   "Rest, hydration, caffeine, blood patch"],
    ]
    two_col_table(
        comp[0], comp[1:], st, story,
        col_widths=[3.2*cm, 5.7*cm, 6.1*cm]
    )

    story.append(Paragraph("Absolute Contraindications to Neuraxial Blockade", st["slide_title"]))
    contra = [
        "Patient refusal",
        "Localised infection at injection site",
        "Allergy to intended LA agent",
        "Raised intracranial pressure (risk of brainstem herniation with dural puncture)",
        "Inability to maintain stillness during needle placement",
        "Uncorrected hypovolaemia (relative to absolute depending on urgency)",
    ]
    for c in contra:
        story.append(Paragraph(f"<bullet>\u2022</bullet>{c}", st["bullet"]))

    story.append(Spacer(1, 8))
    callout_box(
        "Combined Spinal-Epidural (CSE)",
        [
            "Combines the reliability and speed of spinal with the flexibility of the epidural catheter.",
            "Technique: spinal dose given first through the Tuohy needle before threading the epidural catheter.",
            "Used for: prolonged surgeries, labour analgesia, where post-op epidural analgesia is also needed.",
        ],
        HexColor("#E8F4FD"), st, story
    )
    story.append(PageBreak())


# ── SLIDE: INDUCTION / MAINTENANCE / EMERGENCE ────────────────────────────────

def slide_phases(story, st):
    section_banner("12  |  Induction, Maintenance & Emergence", MID_BLUE, story)
    story.append(Spacer(1, 4))

    phases = [
        (
            "INDUCTION",
            TEAL_ACC,
            [
                "Pre-oxygenation (3–5 min of 100% O₂) — builds N₂ washout oxygen reserve",
                "IV induction: propofol ± opioid ± NMBA; or gas induction (sevoflurane) in children",
                "Laryngoscopy & intubation / LMA insertion",
                "RSI (Rapid Sequence Induction): thiopental/propofol + succinylcholine (or high-dose rocuronium) → Sellick's manoeuvre → immediate intubation; used when aspiration risk is high",
                "Check: bilateral breath sounds, ETCO₂ waveform, SpO₂",
            ]
        ),
        (
            "MAINTENANCE",
            MID_BLUE,
            [
                "Inhalational: volatile agent (sevoflurane/isoflurane) + N₂O ± O₂",
                "TIVA: propofol ± remifentanil infusion",
                "Balanced: volatile agent + opioid + NMBA",
                "Monitor: ETCO₂, SpO₂, BIS/depth of anaesthesia, NIBP/IBP, ECG, urine output",
                "Ventilation: volume-controlled or pressure-controlled; PEEP 5–8 cmH₂O; tidal volume 6–8 mL/kg ideal body weight",
                "Fluids: crystalloid (Hartmann's/0.9% NaCl); avoid excess; replace losses",
            ]
        ),
        (
            "EMERGENCE",
            HexColor("#1A7A5E"),
            [
                "Discontinue maintenance agents; reverse NMBA (neostigmine or sugammadex)",
                "Wait for: TOF ratio ≥0.9, spontaneous ventilation, able to follow commands",
                "Extubate awake (preferred) or deep — depends on aspiration risk, airway",
                "Complications on emergence: laryngospasm, bronchospasm, hypertension, shivering, PONV",
                "Rapid emergence desirable (e.g. carotid endarterectomy) for immediate neurological assessment",
            ]
        ),
    ]
    for title, color, points in phases:
        header = Table([[Paragraph(title, st["section_heading"])]], colWidths=[W - 4*cm])
        header.setStyle(TableStyle([
            ("BACKGROUND",    (0,0), (-1,-1), color),
            ("TOPPADDING",    (0,0), (-1,-1), 7),
            ("BOTTOMPADDING", (0,0), (-1,-1), 7),
            ("LEFTPADDING",   (0,0), (-1,-1), 14),
            ("ROUNDEDCORNERS", [4]),
        ]))
        story.append(header)
        for pt in points:
            story.append(Paragraph(f"<bullet>\u2022</bullet>{pt}", st["bullet"]))
        story.append(Spacer(1, 10))
    story.append(PageBreak())


# ── SLIDE: AIRWAY ─────────────────────────────────────────────────────────────

def slide_airway(story, st):
    section_banner("13  |  Airway Management", MID_BLUE, story)
    story.append(Paragraph(
        "Airway management is the most critical skill in anaesthesia. Inability to secure the airway "
        "is the leading cause of anaesthesia-related morbidity and mortality.",
        st["body"]
    ))
    story.append(Spacer(1, 6))

    story.append(Paragraph("Airway Assessment — Predictors of Difficult Intubation", st["slide_title"]))
    mnemonic_data = [
        ["Mnemonic", "Meaning / Assessment Tool"],
        ["LEMON",    "Look (facial features), Evaluate 3-3-2 rule, Mallampati score, Obstruction, Neck mobility"],
        ["Mallampati\nClass I–IV", "Class I: full tonsillar pillars & uvula visible; Class IV: only hard palate visible (difficult)"],
        ["Mouth Opening", "< 3 cm = restricted; < 2 cm = very difficult"],
        ["Thyromental\ndistance", "< 6.5 cm predicts difficult intubation (Patil's test)"],
        ["Neck Mobility",  "Reduced in RA, ankylosing spondylitis, cervical spondylosis"],
    ]
    two_col_table(mnemonic_data[0], mnemonic_data[1:], st, story,
                  col_widths=[3.2*cm, 11.8*cm])

    story.append(Paragraph("Airway Devices", st["slide_title"]))
    devices = [
        "<b>Face mask</b>: Bag-valve-mask ventilation; temporary",
        "<b>Oropharyngeal airway (OPA / Guedel)</b>: Maintains airway in unconscious patient; does NOT protect against aspiration",
        "<b>Nasopharyngeal airway (NPA)</b>: Better tolerated when semi-conscious; caution in base-of-skull fracture",
        "<b>Laryngeal Mask Airway (LMA / supraglottic)</b>: Sits above glottis; no intubation; does NOT prevent aspiration; used for most elective surgeries",
        "<b>Endotracheal Tube (ETT)</b>: Gold standard for airway protection; cuffed (adults), uncuffed (children &lt; 8 yr); confirm with ETCO₂ + chest auscultation",
        "<b>Video laryngoscopy</b> (GlideScope, McGrath): Improved view in difficult airways; now standard for anticipated difficult intubation",
        "<b>Surgical airway</b> (cricothyrotomy, tracheotomy): Emergency access when cannot intubate / cannot ventilate",
    ]
    for d in devices:
        story.append(Paragraph(f"<bullet>\u2022</bullet>{d}", st["bullet"]))

    story.append(Spacer(1, 6))
    callout_box(
        "DAS Difficult Airway Algorithm (simplified)",
        [
            "Plan A: Direct/video laryngoscopy — max 3 attempts",
            "Plan B: Supraglottic airway device (LMA)",
            "Plan C: Mask ventilation — attempt to maintain oxygenation",
            "Plan D: Emergency front-of-neck access (eFONA) — scalpel cricothyrotomy",
            "At each step: DECLARE the problem, call for help, optimise position",
        ],
        HexColor("#FFE8E8"), st, story
    )
    story.append(PageBreak())


# ── SLIDE: MONITORING ─────────────────────────────────────────────────────────

def slide_monitoring(story, st):
    section_banner("14  |  Intraoperative Monitoring", MID_BLUE, story)
    story.append(Paragraph(
        "Monitoring is mandatory throughout anaesthesia. The Association of Anaesthetists (AAGBI) "
        "and ASA standards define minimum monitoring requirements.",
        st["body"]
    ))
    story.append(Spacer(1, 6))

    monitoring = [
        ["Parameter",        "Monitor / Method",                      "Clinical Significance"],
        ["SpO₂",             "Pulse oximetry",                        "Early detection of hypoxia; waveform quality indicates perfusion"],
        ["ETCO₂",            "Capnography (waveform)",                 "Confirm intubation; detect air embolism, malignant hyperthermia, circuit disconnection"],
        ["ECG",              "3- or 5-lead; V5 for ischaemia",        "Rate, rhythm, ST changes, ischaemia; continuous ST analysis for high-risk patients"],
        ["Blood Pressure",   "NIBP (every 3–5 min) or IBP (arterial line)", "Haemodynamic stability; IBP for continuous beat-to-beat monitoring in major surgery"],
        ["Airway Pressures", "Peak, plateau, PEEP",                   "Detect bronchospasm, pneumothorax, obstruction; lung-protective ventilation"],
        ["Depth of Anaesthesia", "BIS (Bispectral Index) / Entropy",  "Target BIS 40–60 intraoperatively; reduces awareness risk and anaesthetic consumption"],
        ["Neuromuscular",    "TOF (acceleromyography)",               "Avoid residual paralysis; guide reversal timing"],
        ["Temperature",      "Nasopharyngeal / oesophageal / bladder","Prevent hypothermia (&lt;36°C); detect malignant hyperthermia"],
        ["Urine Output",     "Urinary catheter (major surgery)",       "Target ≥0.5 mL/kg/h; guide fluid management"],
        ["Invasive CVP",     "Central venous catheter",               "Volume status, drug delivery; in major/cardiac surgery"],
    ]
    two_col_table(
        monitoring[0], monitoring[1:], st, story,
        col_widths=[3.2*cm, 4.8*cm, 7.0*cm]
    )

    callout_box(
        "BIS and Depth of Anaesthesia",
        [
            "BIS (0–100): 0 = flat EEG; 100 = fully awake. Target 40–60 for surgical anaesthesia.",
            "BIS 60–80 = sedation; BIS 40–60 = general anaesthesia; BIS < 40 = deep anaesthesia.",
            "Clinical trials have not demonstrated BIS to be definitively superior to appropriate volatile agent MAC monitoring for preventing awareness, but it remains widely used.",
        ],
        HexColor("#F0F8FF"), st, story
    )
    story.append(PageBreak())


# ── SLIDE: COMPLICATIONS ──────────────────────────────────────────────────────

def slide_complications(story, st):
    section_banner("15  |  Complications & Intraoperative Awareness", MID_BLUE, story)

    comps = [
        ["Complication",                   "Mechanism / Cause",                   "Management"],
        ["PONV\n(Post-op nausea/vomiting)","Opioids, N₂O, volatile agents, female sex, non-smoker, Hx of PONV", "Ondansetron 4 mg; dexamethasone 4–8 mg; droperidol; TIVA; avoid N₂O"],
        ["Laryngospasm",                   "Partial/complete glottic closure during light anaesthesia", "100% O₂, CPAP, deepening/propofol 0.5 mg/kg, suxamethonium 0.1–1 mg/kg"],
        ["Bronchospasm",                   "Airway reactivity; light anaesthesia; histamine release", "Deepen anaesthesia, salbutamol nebuliser, IV magnesium, adrenaline if severe"],
        ["Hypotension",                    "Anaesthetic agents, bleeding, vasodilation, positional", "Vasopressors (phenylephrine, ephedrine, noradrenaline); fluid bolus; treat cause"],
        ["Hypothermia",                    "Heat loss (radiation, convection, evaporation); open cavity", "Forced-air warming blanket, warm IV fluids, theatre temperature"],
        ["Malignant Hyperthermia",         "Ryanodine receptor mutation; triggered by volatile agents or suxamethonium", "STOP TRIGGER AGENT; dantrolene 2.5 mg/kg IV; 100% O₂; cool patient; treat hyperkalaemia"],
        ["Anaphylaxis",                    "NMBAs, latex, antibiotics, colloids, chlorhexidine", "Adrenaline 0.5 mg IM (1:1000); stop offending agent; IV fluids; bronchodilators; steroids"],
    ]
    two_col_table(comps[0], comps[1:], st, story,
                  col_widths=[3.0*cm, 5.0*cm, 7.0*cm])

    story.append(Paragraph("Intraoperative Awareness", st["slide_title"]))
    for it in [
        "Incidence ~0.1–0.2% of general anaesthetics; higher in cardiac surgery (1.5%) and obstetrics (0.4%)",
        "Risk factors: light anaesthesia, TIVA without BIS, difficult intubation, paralysis without adequate depth, vaporiser malfunction",
        "Consequences: anxiety, PTSD, nightmares, flashbacks",
        "Prevention: adequate volatile agent ≥0.5 MAC, BIS monitoring, avoid paralysis without confirmed adequate hypnosis",
        "If aware: benzodiazepines can be given for amnesia; debrief patient post-operatively; offer psychological support",
        "Source: Morgan & Mikhail's Clinical Anesthesiology, 7e",
    ]:
        story.append(Paragraph(f"<bullet>\u2022</bullet>{it}", st["bullet"]))
    story.append(PageBreak())


# ── SLIDE: SPECIAL POPULATIONS ───────────────────────────────────────────────

def slide_special(story, st):
    section_banner("16  |  Special Populations", MID_BLUE, story)

    pops = [
        (
            "Paediatric Anaesthesia",
            [
                "Higher O₂ consumption; smaller FRC; prone to hypoxia — pre-oxygenate well",
                "Gas induction (sevoflurane) often preferred in children due to fear of needles; halothane still used in resource-limited settings",
                "Uncuffed ETT preferred < 8 yr (cuffed acceptable with careful pressure monitoring)",
                "Formulae: ETT size = (age/4) + 4; depth = (age/2) + 12 cm at lip",
                "Higher sensitivity to volatile agents — MAC highest in infants",
                "Paediatric doses: atropine 20 mcg/kg, propofol 2–4 mg/kg, suxamethonium 2 mg/kg",
                "Post-op: croup risk; pain assessment (FLACC scale); consider caudal block",
            ]
        ),
        (
            "Obstetric Anaesthesia",
            [
                "Aspiration risk — full stomach precautions (RSI with cricoid pressure); antacid pre-med (sodium citrate)",
                "Aortocaval compression — left lateral tilt (≥15°) from 20 weeks gestation",
                "Regional preferred over general (lower maternal mortality); most elective LSCS under spinal",
                "Spinal for LSCS: hyperbaric bupivacaine 0.5% 2–2.5 mL + fentanyl 25 mcg",
                "Failed intubation more common in obstetric patients (1:300 vs 1:2500 in general population)",
                "General anaesthesia for LSCS: RSI → thiopental 5–7 mg/kg or propofol + suxamethonium",
            ]
        ),
        (
            "Cardiac / High-Risk Patients",
            [
                "Pre-op: optimise cardiac function; continue β-blockers; hold ACEi/ARB morning of surgery",
                "Etomidate or ketamine for induction in haemodynamic instability",
                "5-lead ECG with V5 lead continuous ST monitoring",
                "Arterial line (IBP) mandatory for major surgery",
                "Avoid tachycardia — increases O₂ demand, reduces diastolic filling time",
                "Target MAP ≥65 mmHg; avoid large swings in heart rate and blood pressure",
            ]
        ),
    ]
    for title, points in pops:
        story.append(Paragraph(title, st["slide_title"]))
        for pt in points:
            story.append(Paragraph(f"<bullet>\u2022</bullet>{pt}", st["bullet"]))
        story.append(Spacer(1, 8))
    story.append(PageBreak())


# ── SLIDE: PACU ───────────────────────────────────────────────────────────────

def slide_pacu(story, st):
    section_banner("17  |  Post-Anaesthesia Care (PACU)", MID_BLUE, story)
    story.append(Paragraph(
        "The PACU (Recovery Room) provides close monitoring during the critical period of "
        "emergence from anaesthesia, when complications are most likely.",
        st["body"]
    ))
    story.append(Spacer(1, 6))

    story.append(Paragraph("Aldrete / Modified Aldrete Score — Discharge Criteria", st["slide_title"]))
    aldrete = [
        ["Parameter",        "Score 2",                    "Score 1",                "Score 0"],
        ["Activity",         "Moves 4 extremities",        "Moves 2 extremities",    "Moves 0 extremities"],
        ["Respiration",      "Breathes deeply, coughs",    "Dyspnoea / limited",     "Apnoeic"],
        ["Circulation",      "BP ±20% of pre-op",          "BP ±20–49% of pre-op",   "BP ±50% of pre-op"],
        ["Consciousness",    "Fully awake",                "Arousable on call",      "Not responding"],
        ["SpO₂",             "≥92% on room air",           "Needs O₂ to maintain ≥90%","<90% with O₂"],
    ]
    two_col_table(
        aldrete[0], aldrete[1:], st, story,
        col_widths=[2.8*cm, 3.7*cm, 4.0*cm, 4.5*cm]
    )
    story.append(Paragraph("Discharge score: ≥9/10 (or ≥8/10 with escort)", st["body_small"]))
    story.append(Spacer(1, 8))

    story.append(Paragraph("Common PACU Problems", st["slide_title"]))
    pacu_probs = [
        "<b>Hypoxia</b>: residual muscle relaxation, atelectasis, airway obstruction — O₂, position, reversal",
        "<b>PONV</b>: ondansetron, metoclopramide, dexamethasone; repositioning; avoid opioids",
        "<b>Pain</b>: multimodal analgesia — paracetamol, NSAIDs, opioids, regional; WHO pain ladder",
        "<b>Hypotension</b>: bleeding, vasodilation, dehydration — IV fluids, vasopressors, identify cause",
        "<b>Hypertension</b>: pain, bladder distension, anxiety, pre-existing HTN — treat cause, labetalol/hydralazine",
        "<b>Shivering</b>: hypothermia, volatile agents — pethidine 25 mg IV, forced-air warming",
        "<b>Urinary retention</b>: opioids, anticholinergics, regional block — in/out catheterisation",
        "<b>Delayed emergence</b>: prolonged drug effect, hypothermia, metabolic — reversal agents, active warming",
    ]
    for p in pacu_probs:
        story.append(Paragraph(f"<bullet>\u2022</bullet>{p}", st["bullet"]))
    story.append(PageBreak())


# ── SLIDE: SUMMARY & CLINICAL PEARLS ─────────────────────────────────────────

def slide_summary(story, st):
    section_banner("18  |  Key Summary & Clinical Pearls", DEEP_NAVY, story)
    story.append(Spacer(1, 6))

    pearls = [
        ("Pre-op assessment is essential", "Identify difficult airway, optimise comorbidities, confirm fasting status, document ASA class."),
        ("Pre-oxygenation buys time", "3–5 minutes of 100% O₂ provides an oxygen reserve — critical in hypoxia-prone or difficult airway patients."),
        ("Induction = highest risk period", "Maximum haemodynamic instability at induction; be ready for hypotension, laryngospasm, aspiration."),
        ("RSI for full stomach", "Propofol/thiopental + succinylcholine (or rocuronium 1.2 mg/kg) + cricoid pressure; avoid bag-mask ventilation."),
        ("Confirm tube placement", "ETCO₂ waveform is the GOLD STANDARD; auscultation alone is insufficient."),
        ("Balanced anaesthesia reduces side effects", "Combining agents at lower doses improves haemodynamic stability and reduces dose-dependent toxicity."),
        ("Sevoflurane = most versatile volatile agent", "Suitable for induction AND maintenance; low blood solubility; minimal airway irritation."),
        ("Sugammadex revolutionised RSI", "Reverses rocuronium at any depth rapidly — safer alternative to succinylcholine for RSI in many centres."),
        ("Malignant hyperthermia = emergency", "Stop volatile/succinylcholine; dantrolene 2.5 mg/kg immediately; life-threatening if delayed."),
        ("Regional anaesthesia = preferred in obstetrics", "Lower maternal mortality, avoids difficult airway, better neonatal outcomes."),
        ("Always have a plan B (and C)", "For difficult airway: Plan A → B → C → D (eFONA). Declare early, call for help."),
        ("Post-op pain management is planned pre-operatively", "Multimodal analgesia; regional blocks reduce opioid requirements and speed recovery."),
    ]

    for num, (title, body) in enumerate(pearls, 1):
        data = [[
            Paragraph(f"<b>{num:02d}</b>", st["big_stat"]),
            [
                Paragraph(f"<b>{title}</b>", st["callout_title"]),
                Paragraph(body, st["callout_body"]),
            ]
        ]]
        t = Table(data, colWidths=[1.2*cm, W - 4*cm - 1.4*cm])
        t.setStyle(TableStyle([
            ("BACKGROUND",    (0,0), (-1,-1), PALE_BG if num % 2 == 0 else white),
            ("TOPPADDING",    (0,0), (-1,-1), 6),
            ("BOTTOMPADDING", (0,0), (-1,-1), 6),
            ("LEFTPADDING",   (0,0), (-1,-1), 8),
            ("RIGHTPADDING",  (0,0), (-1,-1), 8),
            ("VALIGN",        (0,0), (-1,-1), "TOP"),
            ("LINEBELOW",     (0,0), (-1,-1), 0.3, HexColor("#D0D8E4")),
        ]))
        story.append(t)

    story.append(Spacer(1, 16))
    callout_box(
        "Sources",
        [
            "Miller's Anesthesia, 2-Volume Set, 10th Edition (Gropper et al.) — Elsevier",
            "Morgan & Mikhail's Clinical Anesthesiology, 7th Edition — McGraw-Hill",
            "Barash, Cullen & Stoelting's Clinical Anesthesia, 9th Edition — Wolters Kluwer",
        ],
        HexColor("#E8ECF0"), st, story
    )
    story.append(PageBreak())


# ── BACK COVER ─────────────────────────────────────────────────────────────────

def build_back_cover(story, st):
    data = [[Paragraph(
        "<br/><br/><br/><br/>"
        "<b>ANAESTHESIA</b><br/>"
        "Principles, Types, Drugs &amp; Clinical Practice<br/><br/>"
        '<font color="#00B4D8">For Medical Students | Intermediate Level</font><br/><br/><br/>'
        "Based on authoritative textbooks:<br/>"
        "Miller's Anesthesia 10e · Morgan &amp; Mikhail 7e · Barash 9e",
        st["cover_subtitle"]
    )]]
    t = Table(data, colWidths=[W - 4*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), DEEP_NAVY),
        ("TOPPADDING",    (0,0), (-1,-1), 40),
        ("BOTTOMPADDING", (0,0), (-1,-1), 60),
        ("ALIGN",         (0,0), (-1,-1), "CENTER"),
    ]))
    story.append(t)


# ── PAGE DECORATION ────────────────────────────────────────────────────────────

def on_page(canvas, doc):
    canvas.saveState()
    # Top bar
    canvas.setFillColor(DEEP_NAVY)
    canvas.rect(0, H - 18, W, 18, fill=1, stroke=0)
    # Top text
    canvas.setFont("Helvetica-Bold", 8)
    canvas.setFillColor(TEAL_ACC)
    canvas.drawString(2*cm, H - 12, "ANAESTHESIA — Medical Student Presentation")
    canvas.setFont("Helvetica", 8)
    canvas.setFillColor(HexColor("#AECBEB"))
    canvas.drawRightString(W - 2*cm, H - 12, "Miller's 10e · Morgan & Mikhail 7e")
    # Bottom bar
    canvas.setFillColor(HexColor("#E8ECF0"))
    canvas.rect(0, 0, W, 16, fill=1, stroke=0)
    canvas.setFont("Helvetica", 8)
    canvas.setFillColor(HexColor("#555555"))
    canvas.drawCentredString(W/2, 5, f"Page {doc.page}")
    canvas.restoreState()


def on_page_later(canvas, doc):
    on_page(canvas, doc)


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

def build():
    OUT = "/home/daytona/workspace/anesthesia-pdf/Anaesthesia_Presentation.pdf"
    doc = BaseDocTemplate(
        OUT,
        pagesize=A4,
        leftMargin=2*cm, rightMargin=2*cm,
        topMargin=2.5*cm, bottomMargin=2.2*cm,
    )
    frame = Frame(
        doc.leftMargin, doc.bottomMargin,
        doc.width, doc.height,
        id="main"
    )
    template = PageTemplate(id="main", frames=[frame],
                            onPage=on_page, onPageEnd=on_page_later)
    doc.addPageTemplates([template])

    st = make_styles()
    story = []

    build_cover(story, st)
    build_toc(story, st)
    slide_history(story, st)
    slide_definition(story, st)
    slide_triad(story, st)
    slide_types(story, st)
    slide_preop(story, st)
    slide_inhalational(story, st)
    slide_iv_agents(story, st)
    slide_opioids(story, st)
    slide_nmba(story, st)
    slide_local(story, st)
    slide_regional(story, st)
    slide_phases(story, st)
    slide_airway(story, st)
    slide_monitoring(story, st)
    slide_complications(story, st)
    slide_special(story, st)
    slide_pacu(story, st)
    slide_summary(story, st)
    build_back_cover(story, st)

    doc.build(story)
    print(f"PDF written to: {OUT}")
    return OUT


if __name__ == "__main__":
    build()
Running Command

cd /home/daytona/workspace/anesthesia-pdf && python build_presentation.py 2>&1

Running Command

ls -lh /home/daytona/workspace/anesthesia-pdf/Anaesthesia_Presentation.pdf

Running Command

python3 -c " from pypdf import PdfReader r = PdfReader('/home/daytona/workspace/anesthesia-pdf/Anaesthesia_Presentation.pdf') print(f'Pages: {len(r.pages)}') for i, p in enumerate(r.pages[:5]): t = p.extract_text() print(f'--- Page {i+1} ---') print(t[:200]) "

Your presentation is ready!

Anaesthesia Presentation

PDF Document · PDF


What's Inside — 29 pages, 18 sections

#SectionKey Content
01HistoryTimeline from ether (1842) to sevoflurane/desflurane
02Definition & Core ConceptsGoals of anaesthesia; balanced anaesthesia principle
03The Anaesthetic TriadHypnosis, analgesia, muscle relaxation; MAC explained
04Types of AnaesthesiaGeneral, regional, local, monitored anaesthesia care
05Pre-op AssessmentASA classification (I-VI), airway assessment, fasting rules
06Inhalational AgentsSevoflurane, desflurane, isoflurane, N₂O, halothane - full drug table with MAC, blood:gas ratios
07IV Anaesthetic AgentsPropofol, etomidate, ketamine, thiopental, midazolam, dexmedetomidine; TIVA
08OpioidsFentanyl, remifentanil, morphine, sufentanil - doses, durations, side effects
09Muscle RelaxantsSuccinylcholine, rocuronium, vecuronium, atracurium; reversal (neostigmine/sugammadex)
10Local AnaestheticsLidocaine, bupivacaine, ropivacaine; Na⁺ channel block; LAST management
11Regional & NeuraxialSpinal vs epidural comparison table; CSE; contraindications
12Induction/Maintenance/EmergenceRSI, TIVA, volatile maintenance, extubation criteria
13Airway ManagementLEMON, Mallampati, devices (ETT/LMA/video laryngoscopy); DAS algorithm
14Intraoperative MonitoringSpO₂, ETCO₂, ECG, BIS, TOF, IBP — full table
15Complications & AwarenessPONV, laryngospasm, malignant hyperthermia, anaphylaxis, awareness
16Special PopulationsPaediatric, obstetric, cardiac anaesthesia
17PACUAldrete score, post-op problems and management
18Clinical Pearls12 high-yield take-home points
Sources: Miller's Anesthesia 10e · Morgan & Mikhail's Clinical Anesthesiology 7e · Barash 9e
This is a shared conversation. Sign in to Orris to start your own chat.