SAQ’s& VSAQ’s- • *****Hemodynamic changes during normal pregnancy. • ***Cardiovascular changes in pregnancy. • ***Skin changes during pregnancy. • ***Breast changes in pregnancy. • *****Causes of edema in pregnancy. Generate answers for University proffs with flowcharts and diagrams in pdf format

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

ls /home/daytona/workspace/ 2>/dev/null || echo "workspace empty"

Running Command

mkdir -p /home/daytona/workspace/pregnancy-saq && python3 -c "import reportlab; print('reportlab ok')" && python3 -c "import matplotlib; print('matplotlib ok')"

Writing File

~/pregnancy-saq/generate_pdf.py

#!/usr/bin/env python3
"""
Pregnancy SAQ/VSAQ PDF Generator
Topics: Hemodynamic Changes, Cardiovascular Changes, Skin Changes,
        Breast Changes, Causes of Edema in Pregnancy
"""

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib.patches as FancyBboxPatch
from matplotlib.patches import FancyArrowPatch
import numpy as np
import os
import io

from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
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,
    Image as RLImage, PageBreak, HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

# ── Color Palette ──────────────────────────────────────────────────────────────
C_NAVY    = HexColor('#0D2B4E')
C_ROYAL   = HexColor('#1A5276')
C_SKY     = HexColor('#2980B9')
C_LIGHT   = HexColor('#D6EAF8')
C_GOLD    = HexColor('#F39C12')
C_ORANGE  = HexColor('#E67E22')
C_RED     = HexColor('#C0392B')
C_GREEN   = HexColor('#1E8449')
C_LGREEN  = HexColor('#D5F5E3')
C_PURPLE  = HexColor('#7D3C98')
C_LPURPLE = HexColor('#E8DAEF')
C_TEAL    = HexColor('#17A589')
C_LTEAL   = HexColor('#D0ECE7')
C_GREY    = HexColor('#F2F3F4')
C_DGREY   = HexColor('#717D7E')
C_WHITE   = white
C_PINK    = HexColor('#FADBD8')
C_BROWN   = HexColor('#6E2F1A')

OUTPUT_DIR = '/home/daytona/workspace/pregnancy-saq'
OUTPUT_PDF = os.path.join(OUTPUT_DIR, 'Pregnancy_SAQ_VSAQ.pdf')

W, H = A4  # 595.28 x 841.89 points

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

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

title_style = make_style('DocTitle',
    fontSize=22, textColor=C_WHITE, alignment=TA_CENTER,
    fontName='Helvetica-Bold', spaceAfter=4, spaceBefore=4)

part_style = make_style('PartTitle',
    fontSize=17, textColor=C_WHITE, alignment=TA_CENTER,
    fontName='Helvetica-Bold', spaceAfter=4, spaceBefore=4)

heading_style = make_style('SectionH',
    fontSize=13, textColor=C_NAVY, fontName='Helvetica-Bold',
    spaceBefore=10, spaceAfter=4, leftIndent=0)

subh_style = make_style('SubH',
    fontSize=11, textColor=C_ROYAL, fontName='Helvetica-Bold',
    spaceBefore=6, spaceAfter=3)

body_style = make_style('Body',
    fontSize=9.5, textColor=HexColor('#1A1A1A'), fontName='Helvetica',
    leading=14, spaceBefore=2, spaceAfter=2, alignment=TA_JUSTIFY)

bullet_style = make_style('Bullet',
    fontSize=9.5, textColor=HexColor('#1A1A1A'), fontName='Helvetica',
    leading=14, leftIndent=16, bulletIndent=4, spaceBefore=1, spaceAfter=1)

key_style = make_style('Key',
    fontSize=9, textColor=C_NAVY, fontName='Helvetica-Bold',
    leading=13, leftIndent=12, spaceBefore=1, spaceAfter=1)

caption_style = make_style('Caption',
    fontSize=8.5, textColor=C_DGREY, fontName='Helvetica-Oblique',
    alignment=TA_CENTER, spaceBefore=3, spaceAfter=6)

box_style = make_style('Box',
    fontSize=9.5, textColor=HexColor('#1A1A1A'), fontName='Helvetica',
    leading=14, leftIndent=8, rightIndent=8, spaceBefore=3, spaceAfter=3,
    alignment=TA_JUSTIFY)

# ── Helper: colored banner ─────────────────────────────────────────────────────
def banner(text, style, bgcolor):
    return Table([[Paragraph(text, style)]],
                 colWidths=[W - 4*cm],
                 style=TableStyle([
                     ('BACKGROUND', (0,0), (-1,-1), bgcolor),
                     ('ROUNDEDCORNERS', [6,6,6,6]),
                     ('TOPPADDING',    (0,0),(-1,-1), 8),
                     ('BOTTOMPADDING', (0,0),(-1,-1), 8),
                     ('LEFTPADDING',   (0,0),(-1,-1), 14),
                     ('RIGHTPADDING',  (0,0),(-1,-1), 14),
                 ]))

def divider(color=C_SKY):
    return HRFlowable(width="100%", thickness=1.5, color=color,
                      spaceAfter=6, spaceBefore=2)

def info_box(text, bgcolor=C_LIGHT, fgcolor=C_NAVY):
    return Table([[Paragraph(text, make_style('IB', parent='Body',
                    fontSize=9, textColor=fgcolor, leading=13))]],
                 colWidths=[W - 4*cm],
                 style=TableStyle([
                     ('BACKGROUND', (0,0),(-1,-1), bgcolor),
                     ('TOPPADDING',    (0,0),(-1,-1), 6),
                     ('BOTTOMPADDING', (0,0),(-1,-1), 6),
                     ('LEFTPADDING',   (0,0),(-1,-1), 10),
                     ('RIGHTPADDING',  (0,0),(-1,-1), 10),
                     ('BOX', (0,0),(-1,-1), 1, fgcolor),
                 ]))

def two_col_table(rows, h1, h2, c1w=None, c2w=None):
    c1w = c1w or (W-4*cm)*0.42
    c2w = c2w or (W-4*cm)*0.58
    hdr_style = make_style('TH', parent='Body', fontSize=9.5,
                            fontName='Helvetica-Bold', textColor=C_WHITE)
    cell_style = make_style('TC', parent='Body', fontSize=9, leading=13)
    data = [[Paragraph(h1, hdr_style), Paragraph(h2, hdr_style)]]
    for r in rows:
        data.append([Paragraph(r[0], cell_style), Paragraph(r[1], cell_style)])
    ts = TableStyle([
        ('BACKGROUND', (0,0), (-1,0), C_ROYAL),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [C_WHITE, C_GREY]),
        ('TOPPADDING',    (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
        ('LEFTPADDING',   (0,0), (-1,-1), 7),
        ('RIGHTPADDING',  (0,0), (-1,-1), 7),
        ('GRID', (0,0), (-1,-1), 0.5, HexColor('#BDC3C7')),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ])
    return Table(data, colWidths=[c1w, c2w], style=ts)

def three_col_table(rows, h1, h2, h3):
    cw = (W-4*cm)/3
    hdr_style = make_style('TH3', parent='Body', fontSize=9,
                            fontName='Helvetica-Bold', textColor=C_WHITE)
    cell_style = make_style('TC3', parent='Body', fontSize=8.5, leading=13)
    data = [[Paragraph(h1, hdr_style), Paragraph(h2, hdr_style), Paragraph(h3, hdr_style)]]
    for r in rows:
        data.append([Paragraph(r[0], cell_style), Paragraph(r[1], cell_style), Paragraph(r[2], cell_style)])
    ts = TableStyle([
        ('BACKGROUND', (0,0), (-1,0), C_TEAL),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [C_WHITE, C_LTEAL]),
        ('TOPPADDING',    (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
        ('LEFTPADDING',   (0,0), (-1,-1), 6),
        ('RIGHTPADDING',  (0,0), (-1,-1), 6),
        ('GRID', (0,0), (-1,-1), 0.5, HexColor('#BDC3C7')),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ])
    return Table(data, colWidths=[cw, cw, cw], style=ts)

def img_from_fig(fig, dpi=110):
    buf = io.BytesIO()
    fig.savefig(buf, format='png', dpi=dpi, bbox_inches='tight',
                facecolor=fig.get_facecolor())
    buf.seek(0)
    plt.close(fig)
    return buf

# ══════════════════════════════════════════════════════════════════════════════
#  DIAGRAM GENERATORS
# ══════════════════════════════════════════════════════════════════════════════

def draw_hemodynamic_flowchart():
    """Flowchart: Hemodynamic changes through pregnancy trimesters"""
    fig, ax = plt.subplots(figsize=(10, 7), facecolor='#F8FBFF')
    ax.set_xlim(0, 10)
    ax.set_ylim(0, 7)
    ax.axis('off')
    ax.set_facecolor('#F8FBFF')

    def box(ax, x, y, w, h, text, fc, ec='#1A5276', fs=9, bold=False, tc='black'):
        rect = mpatches.FancyBboxPatch((x-w/2, y-h/2), w, h,
            boxstyle="round,pad=0.08", facecolor=fc, edgecolor=ec, linewidth=1.5)
        ax.add_patch(rect)
        fw = 'bold' if bold else 'normal'
        ax.text(x, y, text, ha='center', va='center', fontsize=fs,
                fontweight=fw, color=tc, wrap=True,
                multialignment='center')

    def arrow(ax, x1, y1, x2, y2, color='#1A5276'):
        ax.annotate('', xy=(x2, y2), xytext=(x1, y1),
                    arrowprops=dict(arrowstyle='->', color=color, lw=1.8))

    # Title
    ax.text(5, 6.6, 'HEMODYNAMIC CHANGES DURING NORMAL PREGNANCY',
            ha='center', va='center', fontsize=11, fontweight='bold', color='#0D2B4E')

    # Row 1: Stimulus
    box(ax, 5, 6.0, 4.5, 0.55,
        'Rising Estrogen + Progesterone + hCG + Relaxin',
        '#D6EAF8', bold=True, tc='#0D2B4E', fs=9)

    arrow(ax, 5, 5.72, 5, 5.38)

    # Row 2: Three parallel effects
    box(ax, 2.0, 5.1, 2.8, 0.55,
        'Plasma Volume\n+40-50%', '#AED6F1', tc='#1A5276', bold=True, fs=9)
    box(ax, 5.0, 5.1, 2.8, 0.55,
        'SVR\n-30-50%', '#F9E79F', tc='#784212', bold=True, fs=9)
    box(ax, 8.0, 5.1, 2.8, 0.55,
        'Heart Rate\n+10-15 bpm', '#ABEBC6', tc='#145A32', bold=True, fs=9)

    arrow(ax, 2.0, 4.82, 2.0, 4.38)
    arrow(ax, 5.0, 4.82, 5.0, 4.38)
    arrow(ax, 8.0, 4.82, 8.0, 4.38)

    # Row 3: outcomes
    box(ax, 2.0, 4.1, 2.8, 0.55,
        'Physiologic Anemia\n(Hgb dilution)', '#D6EAF8', tc='#1A5276', fs=8.5)
    box(ax, 5.0, 4.1, 2.8, 0.55,
        'BP falls 5-10 mmHg\n(Nadir: 2nd trimester)', '#FDEBD0', tc='#784212', fs=8.5)
    box(ax, 8.0, 4.1, 2.8, 0.55,
        'Stroke Volume\n+40% (peaks 28-31 wk)', '#D5F5E3', tc='#145A32', fs=8.5)

    # Arrows converging to CO
    arrow(ax, 2.0, 3.82, 3.5, 3.4)
    arrow(ax, 5.0, 3.82, 5.0, 3.4)
    arrow(ax, 8.0, 3.82, 6.5, 3.4)

    box(ax, 5.0, 3.1, 4.0, 0.55,
        'CARDIAC OUTPUT +30-50%\n(peaks 28-34 weeks)', '#1A5276', tc='white',
        bold=True, fs=10, ec='#0D2B4E')

    arrow(ax, 5.0, 2.82, 5.0, 2.38)

    # Labour
    box(ax, 5.0, 2.1, 4.5, 0.55,
        'LABOUR: CO increases further +60-80%\n(autotransfusion + catecholamines)',
        '#C0392B', tc='white', bold=True, fs=9, ec='#922B21')

    arrow(ax, 5.0, 1.82, 5.0, 1.42)

    box(ax, 5.0, 1.2, 5.5, 0.45,
        'Postpartum: Gradual resolution over 2 weeks - 6 months',
        '#E8F8F5', tc='#117A65', fs=8.5, ec='#17A589')

    # Timeline axis
    ax.annotate('', xy=(9.5, 0.55), xytext=(0.5, 0.55),
                arrowprops=dict(arrowstyle='->', color='#717D7E', lw=1.5))
    ax.text(5, 0.35, 'Gestational Age →  (Wk 5 → Wk 40 → Postpartum)',
            ha='center', fontsize=8, color='#717D7E')
    for xv, lbl in [(1.5,'Wk 5'), (3.5,'Wk 20'), (6,'Wk 34'), (8.5,'Term')]:
        ax.axvline(xv, ymin=0.05, ymax=0.12, color='#BDC3C7', lw=1)
        ax.text(xv, 0.65, lbl, ha='center', fontsize=7.5, color='#717D7E')

    plt.tight_layout()
    return img_from_fig(fig)


def draw_co_timeline():
    """Line graph: CO/HR/SV changes over gestational weeks"""
    fig, ax = plt.subplots(figsize=(9, 4), facecolor='#F8FBFF')
    ax.set_facecolor('#F8FBFF')

    weeks = [0, 8, 16, 24, 32, 38, 40, 42]  # 42 = postpartum 6wk
    labels = ['Pre-\npreg', 'Wk 8', 'Wk 16', 'Wk 24', 'Wk 32', 'Wk 38',
              'Labour', 'Post\npartum']

    co   = [100, 115, 130, 140, 148, 145, 180, 105]  # % of baseline
    hr   = [100, 105, 108, 112, 115, 118, 125, 102]
    sv   = [100, 110, 120, 125, 128, 122, 145, 103]
    svr  = [100, 88,  75,  68,  65,  70,  55,  95]

    x = range(len(weeks))

    ax.plot(x, co,  'o-', color='#1A5276', lw=2.5, ms=7, label='Cardiac Output', zorder=5)
    ax.plot(x, hr,  's-', color='#C0392B', lw=2,   ms=6, label='Heart Rate', zorder=4)
    ax.plot(x, sv,  '^-', color='#1E8449', lw=2,   ms=6, label='Stroke Volume', zorder=4)
    ax.plot(x, svr, 'D--',color='#E67E22', lw=2,   ms=6, label='SVR (inverse)', zorder=3, alpha=0.8)

    ax.axhline(100, color='#BDC3C7', ls='--', lw=1, label='Baseline')
    ax.fill_between(x, co, 100, alpha=0.08, color='#1A5276')

    ax.set_xticks(list(x))
    ax.set_xticklabels(labels, fontsize=8.5)
    ax.set_ylabel('% of Pre-pregnancy Value', fontsize=9)
    ax.set_title('Hemodynamic Parameters Throughout Pregnancy', fontsize=10.5,
                 fontweight='bold', color='#0D2B4E')
    ax.legend(fontsize=8, loc='upper left', framealpha=0.9)
    ax.set_ylim(50, 200)
    ax.grid(axis='y', alpha=0.3)
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)

    # Annotations
    ax.annotate('Peak CO\n28-34 wks', xy=(4, 148), xytext=(3, 168),
                fontsize=7.5, color='#1A5276',
                arrowprops=dict(arrowstyle='->', color='#1A5276', lw=1.2))
    ax.annotate('Labour spike\n+60-80%', xy=(6, 180), xytext=(5.2, 192),
                fontsize=7.5, color='#C0392B',
                arrowprops=dict(arrowstyle='->', color='#C0392B', lw=1.2))

    plt.tight_layout()
    return img_from_fig(fig)


def draw_cardiovascular_diagram():
    """Diagram: Cardiovascular adaptations"""
    fig, axes = plt.subplots(1, 2, figsize=(12, 5.5), facecolor='#F8FBFF')
    fig.suptitle('Cardiovascular Adaptations in Pregnancy', fontsize=11,
                 fontweight='bold', color='#0D2B4E', y=1.01)

    # Left: Cardiac structural changes (annotated heart schematic)
    ax1 = axes[0]
    ax1.set_facecolor('#F8FBFF')
    ax1.set_xlim(0, 10)
    ax1.set_ylim(0, 10)
    ax1.axis('off')
    ax1.set_title('Structural & Functional Changes', fontsize=9.5,
                  fontweight='bold', color='#1A5276')

    def cbox(ax, x, y, w, h, txt, fc, ec='#1A5276', fs=8.5, tc='black'):
        r = mpatches.FancyBboxPatch((x-w/2, y-h/2), w, h,
            boxstyle="round,pad=0.1", facecolor=fc, edgecolor=ec, lw=1.2)
        ax.add_patch(r)
        ax.text(x, y, txt, ha='center', va='center', fontsize=fs,
                color=tc, multialignment='center')

    # Heart schematic (simplified ellipse)
    heart = mpatches.Ellipse((5, 5.5), 3.2, 4.2, facecolor='#FADBD8',
                              edgecolor='#C0392B', lw=2.5, alpha=0.6)
    ax1.add_patch(heart)
    ax1.text(5, 5.5, '♥', ha='center', va='center', fontsize=36,
             color='#C0392B', alpha=0.25)

    changes = [
        (1.2, 8.8, 'LV Wall Thickness\n↑ (eccentric hypertrophy)', '#D6EAF8'),
        (8.8, 8.8, 'LV End-Diastolic\nVolume ↑ 10-12%', '#D5F5E3'),
        (1.2, 5.5, 'Laterally displaced\nApical impulse', '#FDEBD0'),
        (8.8, 5.5, 'Ejection Systolic\nMurmur (Flow murmur)', '#E8DAEF'),
        (1.2, 2.2, 'Palpable RV or\nPulmonary trunk', '#D6EAF8'),
        (8.8, 2.2, 'Prominent JVP\n(no elevation of JVP)', '#D5F5E3'),
    ]
    for cx, cy, txt, fc in changes:
        cbox(ax1, cx, cy, 3.0, 1.0, txt, fc)
        # Arrow toward heart
        if cx < 5:
            ax1.annotate('', xy=(3.5, cy), xytext=(cx+1.5, cy),
                        arrowprops=dict(arrowstyle='->', color='#717D7E', lw=1))
        else:
            ax1.annotate('', xy=(6.5, cy), xytext=(cx-1.5, cy),
                        arrowprops=dict(arrowstyle='->', color='#717D7E', lw=1))

    # Right: BP changes bar chart
    ax2 = axes[1]
    ax2.set_facecolor('#F8FBFF')
    ax2.set_title('Blood Pressure Changes by Trimester', fontsize=9.5,
                  fontweight='bold', color='#1A5276')

    groups = ['Pre-preg', '1st Trim', '2nd Trim\n(Nadir)', '3rd Trim', 'Labour',
              'Postpartum\n2wk']
    sbp = [120, 115, 110, 118, 130, 120]
    dbp = [80,  75,  68,  76,  85,  80]

    x = np.arange(len(groups))
    w2 = 0.35
    b1 = ax2.bar(x - w2/2, sbp, w2, label='Systolic BP', color='#2980B9', alpha=0.85)
    b2 = ax2.bar(x + w2/2, dbp, w2, label='Diastolic BP', color='#E67E22', alpha=0.85)

    ax2.axhline(120, color='#2980B9', ls='--', lw=1, alpha=0.5)
    ax2.axhline(80, color='#E67E22', ls='--', lw=1, alpha=0.5)

    ax2.set_xticks(x)
    ax2.set_xticklabels(groups, fontsize=8)
    ax2.set_ylabel('mmHg', fontsize=9)
    ax2.legend(fontsize=8.5, loc='upper left')
    ax2.set_ylim(50, 155)
    ax2.grid(axis='y', alpha=0.3)
    ax2.spines['top'].set_visible(False)
    ax2.spines['right'].set_visible(False)

    # Value labels
    for bar in b1:
        ax2.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 1,
                 f'{int(bar.get_height())}', ha='center', fontsize=7, color='#1A5276')
    for bar in b2:
        ax2.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 1,
                 f'{int(bar.get_height())}', ha='center', fontsize=7, color='#784212')

    # Shaded 2nd trim
    ax2.axvspan(1.5, 2.5, alpha=0.08, color='green', label='Nadir zone')
    ax2.text(2.0, 148, 'Nadir\nzone', ha='center', fontsize=7, color='#1E8449')

    plt.tight_layout()
    return img_from_fig(fig)


def draw_skin_changes_diagram():
    """Mind-map style diagram for skin changes"""
    fig, ax = plt.subplots(figsize=(11, 7.5), facecolor='#FDFEFE')
    ax.set_xlim(0, 11)
    ax.set_ylim(0, 7.5)
    ax.axis('off')
    ax.set_facecolor('#FDFEFE')

    def rbox(ax, x, y, w, h, txt, fc, ec, fs=8.5, bold=False, tc='black'):
        r = mpatches.FancyBboxPatch((x-w/2, y-h/2), w, h,
            boxstyle="round,pad=0.1", facecolor=fc, edgecolor=ec, lw=1.5)
        ax.add_patch(r)
        fw = 'bold' if bold else 'normal'
        ax.text(x, y, txt, ha='center', va='center', fontsize=fs,
                fontweight=fw, color=tc, multialignment='center')

    def arr(ax, x1, y1, x2, y2):
        ax.annotate('', xy=(x2, y2), xytext=(x1, y1),
                    arrowprops=dict(arrowstyle='->', color='#717D7E', lw=1.5))

    # Central node
    rbox(ax, 5.5, 3.8, 2.5, 0.75, 'SKIN CHANGES\nIN PREGNANCY',
         '#0D2B4E', '#0D2B4E', fs=10.5, bold=True, tc='white')

    # Category: Pigmentary
    rbox(ax, 1.5, 6.2, 2.6, 0.6, 'PIGMENTARY\nCHANGES',
         '#1A5276', '#1A5276', fs=9, bold=True, tc='white')
    arr(ax, 1.5, 5.9, 2.8, 4.15)

    items_pig = [
        (0.8, 5.3, 'Hyperpigmentation\n(90% of women)'),
        (2.5, 5.3, 'Melasma / Chloasma\n(mask of pregnancy, 70%)'),
        (0.8, 4.4, 'Linea Nigra\n(linea alba darkening)'),
        (2.5, 4.4, 'Areolar & genital\nhyperpigmentation'),
    ]
    for xb, yb, txt in items_pig:
        rbox(ax, xb, yb, 2.1, 0.6, txt, '#D6EAF8', '#2980B9', fs=7.8)
        arr(ax, xb, yb+0.3, 1.5, 5.9)

    # Category: Connective tissue
    rbox(ax, 9.5, 6.2, 2.6, 0.6, 'CONNECTIVE TISSUE\nCHANGES',
         '#1E8449', '#1E8449', fs=9, bold=True, tc='white')
    arr(ax, 9.5, 5.9, 8.2, 4.15)

    items_ct = [
        (8.5, 5.3, 'Striae gravidarum\n(stretch marks, 50-80%)'),
        (10.3, 5.3, 'Skin tags\n(molluscum fibrosum\ngravidarum)'),
        (9.3, 4.4, 'Diastasis recti\n(collagen laxity)'),
    ]
    for xb, yb, txt in items_ct:
        rbox(ax, xb, yb, 2.3, 0.65, txt, '#D5F5E3', '#1E8449', fs=7.8)
        arr(ax, xb, yb+0.32, 9.5, 5.9)

    # Category: Vascular
    rbox(ax, 1.5, 1.5, 2.6, 0.6, 'VASCULAR\nCHANGES',
         '#7D3C98', '#7D3C98', fs=9, bold=True, tc='white')
    arr(ax, 1.5, 1.8, 3.2, 3.45)

    items_vasc = [
        (0.8, 2.7, 'Spider angiomata\n(spider nevi)'),
        (2.5, 2.7, 'Palmar erythema'),
        (0.8, 2.0, 'Varicosities\n(legs + hemorrhoids)'),
        (2.5, 2.0, 'Gingival hyperplasia\n& edema'),
    ]
    for xb, yb, txt in items_vasc:
        rbox(ax, xb, yb, 2.1, 0.55, txt, '#E8DAEF', '#7D3C98', fs=7.8)
        arr(ax, xb, yb+0.27, 1.5, 1.8)

    # Category: Hair & Nails
    rbox(ax, 9.5, 1.5, 2.6, 0.6, 'HAIR & NAIL\nCHANGES',
         '#C0392B', '#C0392B', fs=9, bold=True, tc='white')
    arr(ax, 9.5, 1.8, 7.8, 3.45)

    items_hair = [
        (8.5, 2.7, 'Hirsutism\n(facial, abdominal hair)'),
        (10.3, 2.7, 'Telogen effluvium\n(postpartum hair loss)'),
        (8.5, 2.0, 'Nail softening\n& subungual keratosis'),
        (10.3, 2.0, 'Anagen ↑ in late\npregnancy'),
    ]
    for xb, yb, txt in items_hair:
        rbox(ax, xb, yb, 2.2, 0.55, txt, '#FADBD8', '#C0392B', fs=7.8)
        arr(ax, xb, yb+0.27, 9.5, 1.8)

    ax.set_title('Skin Changes in Pregnancy - Overview Diagram',
                 fontsize=11, fontweight='bold', color='#0D2B4E', pad=10)
    plt.tight_layout()
    return img_from_fig(fig)


def draw_breast_changes_diagram():
    """Timeline diagram: breast changes by trimester"""
    fig, ax = plt.subplots(figsize=(11, 5), facecolor='#FFF9F9')
    ax.set_facecolor('#FFF9F9')
    ax.set_xlim(0, 12)
    ax.set_ylim(0, 5)
    ax.axis('off')

    ax.set_title('Breast Changes During Pregnancy - Trimester Timeline',
                 fontsize=11, fontweight='bold', color='#0D2B4E', pad=8)

    # Timeline bar
    ax.add_patch(mpatches.FancyBboxPatch((0.3, 2.2), 11.3, 0.4,
        boxstyle="round,pad=0.05", facecolor='#D6EAF8', edgecolor='#1A5276', lw=1.5))
    ax.text(5.9, 2.42, 'GESTATIONAL TIMELINE', ha='center', va='center',
            fontsize=9, fontweight='bold', color='#1A5276')

    # Phase markers
    phases = [(1.5, '1st Trimester\nWk 1-13', '#2980B9'),
              (4.5, '2nd Trimester\nWk 14-27', '#1E8449'),
              (7.5, '3rd Trimester\nWk 28-40', '#C0392B'),
              (10.5, 'Postpartum\n& Lactation', '#7D3C98')]

    for xp, lbl, col in phases:
        ax.plot([xp, xp], [2.1, 2.6], color=col, lw=2, zorder=5)
        ax.text(xp, 1.95, lbl, ha='center', fontsize=8, color=col, fontweight='bold')

    # Changes per trimester
    tri1 = [
        'Ductal proliferation\n& elongation',
        'Corpus luteum → E & P',
        'hCG peaks Wk 9',
        'Breast tenderness\n& fullness begins',
        'Areolar darkening starts',
    ]
    tri2 = [
        'Lobule development\n(progesterone)',
        'Secretory substances\nin acini',
        'Prolactin levels rise',
        'Size increases\nmarkedly',
        'Areolar glands\nmore prominent',
    ]
    tri3 = [
        'Alveolar cell\ndifferentiation',
        'Lactogenesis initiated',
        'Colostrum production',
        'E & P inhibit milk\nrelease',
        'Maximum lobular\ngrowth',
    ]
    post = [
        'E & P withdrawal',
        'Milk let-down',
        'Myoepithelial cells\nactivated',
        'Acinar involution\npost-lactation',
        'Apoptosis & remodeling',
    ]

    def tri_box(ax, x_center, items, color, light_color):
        for i, item in enumerate(items):
            yp = 4.5 - i * 0.52
            ax.add_patch(mpatches.FancyBboxPatch((x_center-1.35, yp-0.19), 2.7, 0.38,
                boxstyle="round,pad=0.05", facecolor=light_color, edgecolor=color, lw=0.8))
            ax.text(x_center, yp, item, ha='center', va='center',
                    fontsize=7.2, color='#1A1A1A', multialignment='center')

    tri_box(ax, 1.5, tri1, '#2980B9', '#D6EAF8')
    tri_box(ax, 4.5, tri2, '#1E8449', '#D5F5E3')
    tri_box(ax, 7.5, tri3, '#C0392B', '#FADBD8')
    tri_box(ax, 10.5, post, '#7D3C98', '#E8DAEF')

    plt.tight_layout()
    return img_from_fig(fig)


def draw_edema_flowchart():
    """Flowchart: Causes of edema in pregnancy"""
    fig, ax = plt.subplots(figsize=(11, 9), facecolor='#F8FBFF')
    ax.set_xlim(0, 11)
    ax.set_ylim(0, 9)
    ax.axis('off')
    ax.set_facecolor('#F8FBFF')

    def box(ax, x, y, w, h, text, fc, ec='#1A5276', fs=9, bold=False, tc='black'):
        r = mpatches.FancyBboxPatch((x-w/2, y-h/2), w, h,
            boxstyle="round,pad=0.1", facecolor=fc, edgecolor=ec, lw=1.5)
        ax.add_patch(r)
        fw = 'bold' if bold else 'normal'
        ax.text(x, y, text, ha='center', va='center', fontsize=fs,
                fontweight=fw, color=tc, multialignment='center')

    def arr(ax, x1, y1, x2, y2, col='#1A5276'):
        ax.annotate('', xy=(x2, y2), xytext=(x1, y1),
                    arrowprops=dict(arrowstyle='->', color=col, lw=1.8))

    ax.set_title('CAUSES OF EDEMA IN PREGNANCY - Pathophysiology Flowchart',
                 fontsize=11, fontweight='bold', color='#0D2B4E', pad=8)

    # Top: Physiological cause
    box(ax, 5.5, 8.5, 5.5, 0.65, 'PREGNANCY (Normal Physiological State)',
        '#0D2B4E', tc='white', bold=True, fs=10)

    arr(ax, 5.5, 8.17, 5.5, 7.75)

    # Mechanisms row
    mechs = [
        (1.5,  7.3, 2.4, 0.75, '↑ Plasma Volume\n(+40-50%)', '#D6EAF8', '#1A5276'),
        (4.5,  7.3, 2.4, 0.75, '↓ Oncotic Pressure\n(albumin dilution)', '#FDEBD0', '#E67E22'),
        (7.5,  7.3, 2.4, 0.75, '↑ Capillary\nPermeability', '#D5F5E3', '#1E8449'),
        (10.0, 7.3, 2.4, 0.75, 'IVC Compression\n(uterus)', '#E8DAEF', '#7D3C98'),
    ]
    for xb, yb, wb, hb, txt, fc, ec in mechs:
        box(ax, xb, yb, wb, hb, txt, fc, ec, fs=8.5)
        arr(ax, xb, yb-0.37, xb, 6.6)

    # Category split
    box(ax, 2.75, 6.3, 5.0, 0.5, 'PHYSIOLOGICAL EDEMA (Normal - 80% of pregnancies)',
        '#1A5276', tc='white', bold=True, fs=9)
    box(ax, 8.25, 6.3, 4.0, 0.5, 'PATHOLOGICAL EDEMA',
        '#C0392B', tc='white', bold=True, fs=9)

    arr(ax, 2.75, 6.05, 2.75, 5.65)
    arr(ax, 8.25, 6.05, 8.25, 5.65)

    # Physiological
    box(ax, 2.75, 5.3, 4.8, 0.65,
        'Dependent edema: ankles, feet, lower legs\nVulval edema | Physiological weight gain',
        '#D6EAF8', '#1A5276', fs=8.5)

    # Pathological boxes
    path_causes = [
        (6.3, 5.3, 2.2, 0.65, 'PRE-ECLAMPSIA\nHypertension + Proteinuria', '#FADBD8', '#C0392B'),
        (8.8, 5.3, 2.2, 0.65, 'Gestational\nHypertension', '#FDEBD0', '#E67E22'),
        (11.0, 5.3, 1.8, 0.65, 'Cardiac\nFailure', '#E8DAEF', '#7D3C98'),
    ]
    for xb, yb, wb, hb, txt, fc, ec in path_causes:
        box(ax, xb, yb, wb, hb, txt, fc, ec, fs=8)
        arr(ax, xb, yb-0.32, xb, 4.6)

    arr(ax, 2.75, 4.97, 2.75, 4.6)

    # Second tier pathological
    tier2 = [
        (1.5, 4.2, 2.3, 0.65, 'Renal Disease\n(nephrotic syndrome)', '#D6EAF8', '#1A5276'),
        (4.0, 4.2, 2.3, 0.65, 'Deep Vein\nThrombosis (DVT)', '#FADBD8', '#C0392B'),
        (6.5, 4.2, 2.3, 0.65, 'Hypoalbuminemia\n(severe)', '#FDEBD0', '#E67E22'),
        (9.0, 4.2, 2.3, 0.65, 'Hypothyroidism\n(myxedema)', '#D5F5E3', '#1E8449'),
    ]
    for xb, yb, wb, hb, txt, fc, ec in tier2:
        box(ax, xb, yb, wb, hb, txt, fc, ec, fs=8)

    # Pre-eclampsia detail
    box(ax, 5.5, 3.2, 10.5, 0.5,
        'Pre-eclampsia Mechanism: Abnormal trophoblast invasion → ↑ sFlt-1 → Endothelial dysfunction → ↑ Capillary leak → Edema',
        '#FADBD8', '#C0392B', fs=8)

    arr(ax, 5.5, 3.95, 5.5, 3.45)

    # Starling forces box
    box(ax, 5.5, 2.4, 10.5, 0.75,
        "Edema Formation (Starling's Forces): Edema = ↑ Hydrostatic Pressure + ↓ Plasma Oncotic Pressure + ↑ Capillary Permeability + Lymphatic obstruction",
        '#F8F9FA', '#717D7E', fs=8.5, ec='#717D7E')

    # Red flags
    box(ax, 5.5, 1.4, 10.5, 0.75,
        'RED FLAGS: Sudden/severe facial edema | Pitting edema above knee | BP ≥ 140/90 | Proteinuria | Oliguria | Headache / Visual changes',
        '#FDEDEC', '#C0392B', fs=8.5, tc='#922B21', ec='#C0392B')

    plt.tight_layout()
    return img_from_fig(fig)


# ══════════════════════════════════════════════════════════════════════════════
#  PAGE BUILDER
# ══════════════════════════════════════════════════════════════════════════════

def build_document():
    doc = SimpleDocTemplate(
        OUTPUT_PDF,
        pagesize=A4,
        leftMargin=2*cm, rightMargin=2*cm,
        topMargin=2*cm, bottomMargin=2*cm,
        title='Pregnancy SAQ/VSAQ - Obstetrics',
        author='Orris Medical AI',
        subject='SAQ & VSAQ Answers for Obstetrics University Examinations'
    )

    story = []

    # ── COVER PAGE ─────────────────────────────────────────────────────────────
    story.append(Spacer(1, 1.5*cm))
    story.append(banner(
        'OBSTETRICS & GYNECOLOGY', part_style, C_NAVY))
    story.append(Spacer(1, 0.3*cm))
    story.append(banner(
        'SAQ & VSAQ — University Examination Answers', title_style, C_ROYAL))
    story.append(Spacer(1, 0.5*cm))

    cover_topics = [
        ('1', 'Hemodynamic Changes During Normal Pregnancy', '*****'),
        ('2', 'Cardiovascular Changes in Pregnancy', '***'),
        ('3', 'Skin Changes During Pregnancy', '***'),
        ('4', 'Breast Changes in Pregnancy', '***'),
        ('5', 'Causes of Edema in Pregnancy', '*****'),
    ]
    topic_style = make_style('TpS', parent='Body', fontSize=10.5,
                              textColor=C_WHITE, leading=16)
    star_style = make_style('StS', parent='Body', fontSize=10.5,
                             textColor=C_GOLD, fontName='Helvetica-Bold')
    data = [[Paragraph(f'<b>{r[0]}.</b>', topic_style),
             Paragraph(r[1], topic_style),
             Paragraph(r[2], star_style)] for r in cover_topics]
    cover_tbl = Table(data, colWidths=[1*cm, 10.5*cm, 2*cm])
    cover_tbl.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,-1), C_NAVY),
        ('ROWBACKGROUNDS', (0,0), (-1,-1), [HexColor('#0D2B4E'), HexColor('#154360')]),
        ('TOPPADDING', (0,0), (-1,-1), 9),
        ('BOTTOMPADDING', (0,0), (-1,-1), 9),
        ('LEFTPADDING', (0,0), (-1,-1), 12),
        ('RIGHTPADDING', (0,0), (-1,-1), 10),
        ('BOX', (0,0), (-1,-1), 1.5, C_GOLD),
    ]))
    story.append(cover_tbl)
    story.append(Spacer(1, 0.5*cm))
    story.append(info_box(
        '<b>Sources:</b> Fuster &amp; Hurst\'s The Heart 15e | Braunwald\'s Heart Disease | '
        'Creasy &amp; Resnik\'s Maternal-Fetal Medicine | Fitzpatrick\'s Dermatology | '
        'Current Surgical Therapy 14e | Harrison\'s Principles of Internal Medicine 22e',
        bgcolor=C_LIGHT, fgcolor=C_NAVY))
    story.append(Spacer(1, 0.3*cm))
    story.append(info_box(
        '<b>Note:</b> ★★★★★ = Highly important exam topics | ★★★ = Important topics',
        bgcolor=HexColor('#FDFDE7'), fgcolor=HexColor('#784212')))

    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # TOPIC 1: HEMODYNAMIC CHANGES
    # ══════════════════════════════════════════════════════════════════════════
    story.append(banner('TOPIC 1 ★★★★★ — HEMODYNAMIC CHANGES DURING NORMAL PREGNANCY',
                        part_style, C_NAVY))
    story.append(Spacer(1, 0.3*cm))
    story.append(info_box(
        '<b>Definition:</b> The series of physiological alterations in blood volume, cardiac '
        'output, heart rate, stroke volume, and vascular resistance that occur during pregnancy '
        'to meet the increased metabolic demands of the mother and fetus.',
        bgcolor=C_LIGHT))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('1.1 Blood Volume Changes', heading_style))
    story.append(divider(C_SKY))
    story.append(two_col_table([
        ['Plasma Volume', 'Increases by 40-50% (up to 1200-1600 mL above baseline); begins at 6-8 weeks, peaks at 30-34 weeks'],
        ['Red Cell Mass', 'Increases by 20-30% (200-250 mL); lags behind plasma expansion'],
        ['Net Effect', 'Physiological (dilutional) anaemia of pregnancy — Hct falls from ~40% to ~32-34%'],
        ['Haemoglobin', 'Falls to ~11 g/dL at lowest; WHO defines anaemia in pregnancy as <11 g/dL'],
        ['Mechanism', 'Aldosterone (↑ 10x) + oestrogen → Na and H2O retention; erythropoietin ↑ → RBC production'],
    ], 'Parameter', 'Detail'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('1.2 Cardiac Output (CO)', heading_style))
    story.append(divider(C_SKY))
    story.append(Paragraph(
        'Cardiac output = Heart Rate × Stroke Volume. Both components increase substantially during pregnancy.',
        body_style))
    story.append(Spacer(1, 0.2*cm))
    story.append(two_col_table([
        ['CO Increase', '+30-50% above pre-pregnancy baseline'],
        ['Onset', 'Begins as early as 5-6 weeks of gestation'],
        ['Peak', '28-34 weeks gestation'],
        ['In Labour', 'Further increase of +60-80% (autotransfusion, catecholamines)'],
        ['Twin Pregnancy', 'Additional +10-15% over singleton pregnancy CO'],
        ['Mechanism', 'Early: ↑ Stroke Volume (40% rise); Late: ↑ Heart Rate (10-15 bpm rise)'],
        ['Postpartum', 'Declines gradually; complete resolution by 2 weeks - 6 months'],
    ], 'Parameter', 'Value / Description'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('1.3 Heart Rate (HR)', heading_style))
    story.append(divider(C_SKY))
    story.append(Paragraph(
        'Heart rate increases progressively throughout pregnancy. The rise begins in the first trimester '
        'and is mediated by hormonal changes (oestrogen, progesterone, relaxin) and increased sympathetic activity.',
        body_style))
    story.append(Spacer(1, 0.2*cm))
    story.append(two_col_table([
        ['HR increase', '+10-15 bpm above pre-pregnancy baseline'],
        ['Peak HR', '~90-100 bpm by third trimester'],
        ['Clinical implication', 'Sinus tachycardia is normal; must distinguish from pathological tachyarrhythmia'],
    ], 'Parameter', 'Value'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('1.4 Blood Pressure & Systemic Vascular Resistance', heading_style))
    story.append(divider(C_SKY))
    story.append(two_col_table([
        ['SVR change', 'Decreases by 30-50% from baseline; nadir in 2nd trimester'],
        ['Mechanism', 'Progesterone, relaxin, prostacyclin, nitric oxide → vasodilation; placental low-resistance bed'],
        ['Systolic BP', 'Falls ~5-10 mmHg; nadir at 16-24 weeks; returns to baseline by 3rd trimester'],
        ['Diastolic BP', 'Falls ~5-15 mmHg; greater fall than systolic (widens pulse pressure)'],
        ['Clinical relevance', 'Supine hypotension syndrome: IVC compression by gravid uterus → ↓ venous return → ↓ CO'],
    ], 'Parameter', 'Details'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('1.5 Stroke Volume (SV)', heading_style))
    story.append(divider(C_SKY))
    story.append(two_col_table([
        ['SV increase', '+40% above baseline'],
        ['Peak', '28-31 weeks gestation'],
        ['Mechanism', 'Increased preload (↑ plasma volume) + decreased afterload (↓ SVR) → Frank-Starling mechanism'],
        ['Late 3rd trimester', 'SV may plateau or slightly decrease (IVC compression in supine)'],
    ], 'Parameter', 'Details'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('1.6 Summary Table: Hemodynamic Changes', heading_style))
    story.append(divider(C_SKY))
    story.append(three_col_table([
        ['Plasma Volume', '+40-50%', 'Begins wk 6, peaks wk 30-34'],
        ['Cardiac Output', '+30-50%', 'Peaks wk 28-34; +80% during labour'],
        ['Heart Rate', '+10-15 bpm', 'Progressive rise throughout pregnancy'],
        ['Stroke Volume', '+40%', 'Peaks wk 28-31; early driver of CO ↑'],
        ['SVR', '-30-50%', 'Nadir in 2nd trimester'],
        ['Blood Pressure', '↓ 5-10 mmHg', 'Nadir 2nd trimester; returns to baseline by term'],
        ['Colloid Oncotic Pressure', 'Decreases', 'Predisposes to edema'],
        ['GFR / Renal blood flow', '↑ 40-65%', 'Increased filtration; mild glycosuria/proteinuria normal'],
    ], 'Parameter', 'Change', 'Timeline / Notes'))
    story.append(Spacer(1, 0.3*cm))

    # Flowchart 1
    story.append(Paragraph('Figure 1: Hemodynamic Changes - Pathophysiology Flowchart', subh_style))
    buf1 = draw_hemodynamic_flowchart()
    img1 = RLImage(buf1, width=W-4.5*cm, height=6*cm)
    story.append(img1)
    story.append(Paragraph('Figure 1: Overview of hemodynamic adaptations during normal pregnancy. '
                           'Hormonal triggers cascade to produce changes in plasma volume, SVR, HR, '
                           'and ultimately cardiac output. Source: Fuster & Hurst\'s The Heart 15e', caption_style))
    story.append(Spacer(1, 0.3*cm))

    # Graph
    story.append(Paragraph('Figure 2: Hemodynamic Parameters vs Gestational Age', subh_style))
    buf2 = draw_co_timeline()
    img2 = RLImage(buf2, width=W-4.5*cm, height=4*cm)
    story.append(img2)
    story.append(Paragraph('Figure 2: Percentage change in cardiac output, heart rate, stroke volume, and SVR '
                           'throughout pregnancy relative to pre-pregnancy baseline. Source: Braunwald\'s Heart Disease', caption_style))

    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # TOPIC 2: CARDIOVASCULAR CHANGES
    # ══════════════════════════════════════════════════════════════════════════
    story.append(banner('TOPIC 2 ★★★ — CARDIOVASCULAR CHANGES IN PREGNANCY',
                        part_style, C_ROYAL))
    story.append(Spacer(1, 0.3*cm))
    story.append(info_box(
        '<b>Key Concept:</b> Pregnancy results in profound cardiovascular adaptations beginning as '
        'early as 6 weeks of gestation. The healthy heart tolerates these well; however, women '
        'with pre-existing cardiac disease are at significant risk.', bgcolor=C_LIGHT))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('2.1 Structural (Anatomic) Cardiac Changes', heading_style))
    story.append(divider(C_SKY))
    story.append(two_col_table([
        ['Cardiac size', 'Increases by ~12%; cardiac silhouette appears enlarged on CXR (normal finding)'],
        ['LV wall thickness', 'Increases (eccentric hypertrophy due to volume overload)'],
        ['LV cavity', 'End-diastolic volume increases by 10-12% (↑ preload)'],
        ['Apex position', 'Displaced laterally and superiorly by elevated diaphragm (from gravid uterus)'],
        ['RV', 'Slightly enlarged; RV may be palpable on exam'],
        ['ECG changes', 'Left axis deviation (diaphragm elevation); sinus tachycardia; non-specific ST-T changes'],
    ], 'Change', 'Details'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('2.2 Clinical Cardiovascular Findings (Normal)', heading_style))
    story.append(divider(C_SKY))
    story.append(info_box(
        '<b>Clinical Pearl:</b> Many pregnancy-related cardiovascular findings can mimic heart disease. '
        'It is important to distinguish normal pregnancy changes from pathological conditions.',
        bgcolor=HexColor('#FDFDE7'), fgcolor=HexColor('#784212')))
    story.append(Spacer(1, 0.2*cm))
    story.append(two_col_table([
        ['Peripheral pulses', 'Collapsing/bounding character (↑ SV + ↓ SVR)'],
        ['JVP', 'Prominent pulsations (without elevation of JVP)'],
        ['Apical impulse', 'Laterally displaced; may be diffuse'],
        ['Palpation', 'Palpable RV or pulmonary trunk in 2nd and 3rd trimester'],
        ['Auscultation S1', 'Louder; S1 splitting common'],
        ['Auscultation S2', 'Persistent splitting, especially in inspiration'],
        ['S3 gallop', 'Common in pregnancy - does NOT indicate heart failure'],
        ['Murmur', 'Soft, short ejection systolic murmur over pulmonary area / LLSB (flow murmur) — benign; disappears postpartum'],
        ['Diastolic murmur', 'ALWAYS pathological even in pregnancy; requires investigation'],
        ['Symptoms (normal)', 'Fatigue, dyspnoea, palpitations, light-headedness — all can be normal in pregnancy'],
    ], 'Finding', 'Description'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('2.3 Venous Changes', heading_style))
    story.append(divider(C_SKY))
    story.append(two_col_table([
        ['Venous tone', 'Reduced (progesterone → smooth muscle relaxation)'],
        ['Venous capacity', 'Increases — accommodates ↑ plasma volume'],
        ['IVC compression', 'Gravid uterus compresses IVC in supine → ↓ venous return → supine hypotension syndrome; managed by left lateral decubitus position'],
        ['Coagulation', 'Hypercoagulable state (↑ fibrinogen, ↑ factors VII, VIII, X, vWF; ↓ Protein S) → DVT/PE risk ↑'],
        ['Varicosities', 'Common in lower limbs and vulva due to ↑ venous pressure + progesterone'],
    ], 'Change', 'Details'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('2.4 Respiratory & Renal Cardiovascular Interactions', heading_style))
    story.append(divider(C_SKY))
    story.append(two_col_table([
        ['Tidal volume', 'Increases by 40% (progesterone stimulates respiratory centre)'],
        ['O2 consumption', 'Increases 20-33% to meet fetal metabolic demands'],
        ['Renal blood flow', 'Increases 40-65%; GFR increases 50%; serum creatinine decreases'],
        ['Cholesterol', 'Increases (needed for steroidogenesis)'],
        ['Insulin resistance', 'Develops in late pregnancy (human placental lactogen)'],
    ], 'Parameter', 'Change in Pregnancy'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('2.5 Cardiovascular Changes by Trimester', heading_style))
    story.append(divider(C_SKY))
    story.append(three_col_table([
        ['1st Trimester', '↑ CO begins; ↑ HR; ↓ BP and SVR start', '↑ Progesterone + Oestrogen → vasodilation'],
        ['2nd Trimester', 'CO peaks early 2nd trim; BP at nadir; plasma vol peaks', 'Placental circulation fully established'],
        ['3rd Trimester', '↑ HR primary driver of CO; supine hypotension appears', 'Uterus compresses IVC in supine position'],
        ['Labour', 'CO surges +60-80%; catecholamines released', 'Pain, anxiety + uterine contractions'],
        ['Immediate Postpartum', 'Autotransfusion ↑ preload acutely; CO ↑ transiently', 'Uterine contraction expels 500mL blood'],
        ['6 weeks PP', 'HR, CO, BP return toward baseline', 'Most hemodynamic changes resolve'],
    ], 'Phase', 'Key Changes', 'Mechanism'))
    story.append(Spacer(1, 0.3*cm))

    # CV diagram
    story.append(Paragraph('Figure 3: Cardiovascular Adaptations in Pregnancy', subh_style))
    buf3 = draw_cardiovascular_diagram()
    img3 = RLImage(buf3, width=W-4.5*cm, height=5.5*cm)
    story.append(img3)
    story.append(Paragraph(
        'Figure 3 (Left) Structural cardiac changes during pregnancy. (Right) Blood pressure changes by trimester. '
        'Source: Braunwald\'s Heart Disease, Fuster & Hurst\'s The Heart 15e', caption_style))

    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # TOPIC 3: SKIN CHANGES
    # ══════════════════════════════════════════════════════════════════════════
    story.append(banner('TOPIC 3 ★★★ — SKIN CHANGES DURING PREGNANCY',
                        part_style, C_TEAL))
    story.append(Spacer(1, 0.3*cm))
    story.append(info_box(
        '<b>Overview:</b> Pregnancy induces widespread cutaneous changes due to hormonal influences '
        '(oestrogen, progesterone, MSH, androgens), mechanical stretching, and immunological alterations. '
        'Most regress after delivery. Some are physiological; a few are specific dermatoses of pregnancy.',
        bgcolor=C_LTEAL, fgcolor=HexColor('#0E6655')))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('3.1 Pigmentary Changes', heading_style))
    story.append(divider(C_TEAL))
    story.append(two_col_table([
        ['Generalised hyperpigmentation', 'Occurs in ≥90% of pregnant women; areolae, genitalia, axillae, nipples most affected. Due to ↑ MSH, β-endorphin, oestrogen, progesterone → ↑ melanocyte activity. Tyrosinase activity ↑ by placental lipids.'],
        ['Linea nigra', 'Darkening of linea alba (midline abdominal line) → becomes linea nigra. Usually appears in 2nd trimester.'],
        ['Melasma (Chloasma)', '"Mask of pregnancy" — diffuse macular hyperpigmentation of forehead, cheeks, bridge of nose. Affects ~70% of pregnant women. Usually regresses postpartum; persists in 30% for months to years. Worsened by UV exposure.'],
        ['Pigmentary demarcation lines', 'Voigt or Futcher lines may appear on legs and other sites.'],
        ['Naevi', 'New melanocytic nevi may appear; pre-existing nevi may enlarge. Monitor for malignant change.'],
    ], 'Feature', 'Details'))
    story.append(Spacer(1, 0.2*cm))
    story.append(info_box(
        '<b>Treatment of Melasma:</b> Sunscreen SPF ≥15 (prevents/minimises). '
        'Topical hydroquinone 4% (post-delivery). Kligman\'s solution (hydroquinone + tretinoin + hydrocortisone). '
        'Azelaic acid, chemical peels — post-delivery. <b>Note: Most treatments are deferred until after delivery.</b>',
        bgcolor=HexColor('#FEF9E7'), fgcolor=HexColor('#784212')))

    story.append(Spacer(1, 0.3*cm))
    story.append(Paragraph('3.2 Vascular Changes', heading_style))
    story.append(divider(C_TEAL))
    story.append(two_col_table([
        ['Spider angiomata (spider naevi)', 'Appear on face, upper trunk, arms in 2nd trimester due to ↑ oestrogen → vasodilation. Usually resolve within 3 months postpartum.'],
        ['Palmar erythema', 'Blotchy redness of palms; present in ~70% of pregnant women. Due to ↑ oestrogen. Resolves postpartum.'],
        ['Varicosities', 'Lower limbs and vulva; due to ↑ venous pressure (IVC compression) + smooth muscle relaxation. May persist postpartum.'],
        ['Gingivitis', 'Gingival hyperplasia and edema due to ↑ capillary permeability + hormonal effect. Risk of pyogenic granuloma.'],
        ['Vulval edema', 'Due to venous congestion + ↑ capillary permeability. Usually physiological.'],
        ['Haemorrhoids', 'Anorectal varicosities; very common due to ↑ venous pressure + constipation.'],
    ], 'Feature', 'Details'))

    story.append(Spacer(1, 0.3*cm))
    story.append(Paragraph('3.3 Connective Tissue Changes', heading_style))
    story.append(divider(C_TEAL))
    story.append(two_col_table([
        ['Striae gravidarum (stretch marks)', 'Linear tears in dermal collagen. Red/purple bands over abdomen, breasts, thighs, buttocks, groin. Appear 2nd-3rd trimester. Affects 50-80% of pregnancies. Risk factors: young age, non-white race, rapid weight gain, large baby, family history. No proven topical prevention. Fade after delivery (remain as white striae albicans).'],
        ['Skin tags (molluscum fibrosum gravidarum)', 'Soft, pedunculated fibro-epithelial polyps on neck, axillae, groin. Common in obesity and pregnancy. Often persist postpartum; can be removed by electrocautery or excision.'],
        ['Diastasis recti', 'Separation of rectus abdominis due to collagen laxity (relaxin + progesterone).'],
    ], 'Feature', 'Details'))

    story.append(Spacer(1, 0.3*cm))
    story.append(Paragraph('3.4 Hair and Nail Changes', heading_style))
    story.append(divider(C_TEAL))
    story.append(two_col_table([
        ['Telogen effluvium', 'Postpartum hair loss (not during pregnancy). After delivery, oestrogen withdrawal → many follicles enter telogen phase simultaneously → diffuse hair shedding at 1-5 months postpartum. Resolves spontaneously by 6-12 months.'],
        ['Hirsutism', 'Increased facial, abdominal, or limb hair due to ↑ androgens from adrenal glands + placenta. Regresses postpartum.'],
        ['Anagen prolongation', 'In late pregnancy, ↑ oestrogen prolongs anagen phase → thick, full hair during pregnancy.'],
        ['Nail changes', 'Nails grow faster; may become brittle, soft, or develop transverse grooves (Beau\'s lines). Subungual keratosis occasionally seen.'],
    ], 'Change', 'Details'))

    story.append(Spacer(1, 0.3*cm))
    story.append(Paragraph('3.5 Specific Dermatoses of Pregnancy', heading_style))
    story.append(divider(C_TEAL))
    story.append(three_col_table([
        ['PUPPP\n(Pruritic Urticarial Papules & Plaques)', 'Most common specific dermatosis. Begins in striae in 3rd trimester. Urticarial papules & plaques, periumbilical sparing. Primigravidae. No fetal risk.', 'Topical steroids; resolves postpartum'],
        ['Pemphigoid gestationis\n(Herpes gestationis)', 'Autoimmune; anti-BP180 antibody. Urticarial → bullous lesions. Periumbilical. Starts 2nd-3rd trimester.', 'Steroids; recurs in subsequent pregnancies; fetal risk (IUGR, prematurity)'],
        ['Intrahepatic cholestasis\nof pregnancy (ICP)', 'Intense pruritus (esp. palms and soles) without rash. ↑ serum bile acids. 3rd trimester.', 'Ursodeoxycholic acid; significant fetal risk (stillbirth); deliver at 37 weeks'],
        ['Atopic eruption of pregnancy\n(prurigo gestationis)', 'Intensely pruritic excoriated papules. Associated with atopic background.', 'Emollients, mild topical steroids'],
    ], 'Condition', 'Features', 'Management'))
    story.append(Spacer(1, 0.3*cm))

    # Skin diagram
    story.append(Paragraph('Figure 4: Skin Changes in Pregnancy — Overview Diagram', subh_style))
    buf4 = draw_skin_changes_diagram()
    img4 = RLImage(buf4, width=W-4.5*cm, height=7*cm)
    story.append(img4)
    story.append(Paragraph(
        'Figure 4: Mind-map summary of skin changes in pregnancy organised by category. '
        'Source: Creasy & Resnik\'s Maternal-Fetal Medicine; Fitzpatrick\'s Dermatology', caption_style))

    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # TOPIC 4: BREAST CHANGES
    # ══════════════════════════════════════════════════════════════════════════
    story.append(banner('TOPIC 4 ★★★ — BREAST CHANGES IN PREGNANCY',
                        part_style, HexColor('#6E2F1A')))
    story.append(Spacer(1, 0.3*cm))
    story.append(info_box(
        '<b>Overview:</b> The breast undergoes dramatic anatomic and physiologic changes during '
        'pregnancy to prepare for lactation. These changes are driven by oestrogen, progesterone, '
        'prolactin, hCG, and placental lactogen acting on ductal, lobular and alveolar structures.',
        bgcolor=HexColor('#FADBD8'), fgcolor=HexColor('#6E2F1A')))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('4.1 Hormonal Cascade Driving Breast Changes', heading_style))
    story.append(divider(HexColor('#C0392B')))
    story.append(two_col_table([
        ['Oestrogen', '↑ Ductal proliferation and elongation; involution of adipose tissue; stimulates pituitary → ↑ prolactin'],
        ['Progesterone', '↑ Lobular (alveolar) development; inhibits actual milk release during pregnancy'],
        ['hCG', 'Prevents corpus luteum degradation; sustains oestrogen + progesterone production; peaks at 9 weeks'],
        ['Prolactin', 'Stimulated by oestrogen; promotes alveolar differentiation and lactogenesis; inhibited from causing milk by high E+P'],
        ['Human Placental Lactogen (hPL)', 'Synergises with prolactin; also responsible for insulin resistance'],
        ['Oxytocin', 'Stimulates myoepithelial cells → milk ejection (let-down reflex) postpartum'],
    ], 'Hormone', 'Role in Breast Development'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('4.2 Anatomic & Physiologic Changes by Trimester', heading_style))
    story.append(divider(HexColor('#C0392B')))
    story.append(three_col_table([
        ['Wk 1-8', 'Corpus luteum → ↑ E + P', 'Breast tenderness, fullness, tingling; ductal proliferation begins'],
        ['Wk 8-13 (1st trim)', 'hCG peaks at wk 9; sustains E + P', 'Ductal system expands; mononuclear cell infiltration; areolae begin to darken'],
        ['Wk 14-20 (2nd trim)', 'Placenta takes over E + P production; prolactin ↑', 'Lobular development most pronounced by wk 20; secretory material accumulates in acini; breast size ↑ markedly'],
        ['Wk 20-28', 'hPL and prolactin rising', 'Myoepithelial cells flatten; epithelial cells enlarge; colostrum production begins'],
        ['Wk 28-40 (3rd trim)', 'Prolactin peaks; E + P inhibit let-down', 'Alveolar differentiation; lactogenesis initiated; colostrum producible; areolae maximally dark; Montgomery glands prominent'],
        ['Labour + Postpartum', 'E + P drop sharply; prolactin maintained', 'Milk production; let-down reflex; breasts engorge; nipple discharge physiological'],
    ], 'Timing', 'Hormonal Driver', 'Breast Change'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('4.3 Visible & Palpable Breast Changes', heading_style))
    story.append(divider(HexColor('#C0392B')))
    story.append(two_col_table([
        ['Breast size', 'Increases throughout pregnancy (ductal + lobular proliferation + fat changes)'],
        ['Areola', 'Enlarges, darkens (hyperpigmentation via MSH + oestrogen); May persist postpartum'],
        ['Nipple', 'Enlarges, becomes more erectile; may have colostrum expression from 16 weeks'],
        ['Montgomery\'s tubercles/glands', 'Hypertrophy during pregnancy (sebaceous glands on areola); secrete lubricating substance for nipple; become prominent bumps'],
        ['Superficial veins', 'Prominent — Haller\'s veins of the breast become visible due to ↑ blood flow'],
        ['Nipple discharge', 'Bilateral colostrum normal from 2nd trimester; bloody nipple discharge in up to 15% of nursing mothers (physiological)'],
        ['Breast tenderness', 'Common first symptom of pregnancy; due to hormonal stimulation of glandular tissue'],
        ['Axillary breast tissue', 'If accessory breast tissue present — may enlarge and become tender'],
    ], 'Feature', 'Details'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('4.4 Postlactational Changes', heading_style))
    story.append(divider(HexColor('#C0392B')))
    story.append(info_box(
        '<b>Involution after lactation:</b> Massive apoptosis and cell death occur in mammary gland. '
        'Connective tissue of lobules changes from loose to dense. Acini lose lining cells. '
        'Basement membrane thickens. Postpartum mammary involution creates a microenvironment that may '
        'promote breast cancer cell growth (important for postpartum breast cancer risk).',
        bgcolor=HexColor('#FADBD8'), fgcolor=HexColor('#6E2F1A')))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('Figure 5: Breast Changes During Pregnancy — Trimester Timeline', subh_style))
    buf5 = draw_breast_changes_diagram()
    img5 = RLImage(buf5, width=W-4.5*cm, height=4.8*cm)
    story.append(img5)
    story.append(Paragraph(
        'Figure 5: Timeline of breast changes from 1st trimester through postpartum, '
        'showing hormonal drivers and structural changes at each stage. '
        'Source: Current Surgical Therapy 14e', caption_style))

    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # TOPIC 5: CAUSES OF EDEMA IN PREGNANCY
    # ══════════════════════════════════════════════════════════════════════════
    story.append(banner('TOPIC 5 ★★★★★ — CAUSES OF EDEMA IN PREGNANCY',
                        part_style, C_NAVY))
    story.append(Spacer(1, 0.3*cm))
    story.append(info_box(
        '<b>Definition:</b> Edema is the abnormal accumulation of fluid in the interstitial space. '
        'In pregnancy, edema is extremely common (physiological in up to 80%) but can also signal '
        'serious pathology. Classification as physiological vs. pathological is clinically critical.',
        bgcolor=C_LIGHT))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph("5.1 Starling's Forces — Mechanism of Edema Formation", heading_style))
    story.append(divider(C_SKY))
    story.append(info_box(
        "<b>Edema = Net filtration force > Lymphatic drainage capacity</b><br/>"
        "Net filtration = (Capillary hydrostatic pressure - Interstitial hydrostatic pressure) "
        "- (Plasma oncotic pressure - Interstitial oncotic pressure) + Capillary permeability<br/><br/>"
        "<b>In Pregnancy:</b> (1) ↑ Capillary hydrostatic pressure (↑ plasma volume, IVC compression), "
        "(2) ↓ Plasma oncotic pressure (albumin dilution), (3) ↑ Capillary permeability (hormonal), "
        "(4) ↑ Venous pressure in lower limbs → all promote edema formation.",
        bgcolor=C_LIGHT, fgcolor=C_NAVY))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('5.2 Physiological Causes (Normal Pregnancy)', heading_style))
    story.append(divider(C_SKY))
    story.append(two_col_table([
        ['Plasma volume expansion (+40-50%)', 'Dilutes serum albumin → ↓ oncotic pressure → fluid moves into interstitium'],
        ['↑ Hydrostatic pressure in lower limbs', 'Compression of pelvic veins and IVC by gravid uterus → venous stasis in lower limbs'],
        ['Hypoalbuminaemia (relative)', 'Serum albumin falls from ~4.0 to ~3.0 g/dL due to dilution → ↓ plasma oncotic pressure'],
        ['↑ Capillary permeability', 'Oestrogen, progesterone, relaxin, prostaglandins → endothelial effects → ↑ permeability'],
        ['Aldosterone ↑ (10x)', 'Na+ and water retention by kidneys → expands plasma volume further'],
        ['Progesterone effects', 'Smooth muscle relaxation → venous dilation → venous pooling → ↓ return → ↑ venous pressure'],
        ['Lymphatic overload', 'Increased fluid load exceeds lymphatic drainage capacity → dependent edema'],
    ], 'Mechanism', 'Explanation'))
    story.append(Spacer(1, 0.2*cm))
    story.append(info_box(
        '<b>Features of Physiological Edema:</b> Bilateral, pitting, dependent (ankles, feet, lower legs, '
        'vulva). Worse in evening, in hot weather, after prolonged standing. Relieved by rest/elevation of limbs. '
        'BP normal, no proteinuria, no symptoms of pre-eclampsia.',
        bgcolor=C_LGREEN, fgcolor=C_GREEN))

    story.append(Spacer(1, 0.3*cm))
    story.append(Paragraph('5.3 Pathological Causes', heading_style))
    story.append(divider(C_SKY))
    story.append(three_col_table([
        ['Pre-eclampsia', 'BP ≥140/90 + proteinuria (≥300 mg/24h) after 20 wks. Pathological trophoblast invasion → sFlt-1 ↑ → endothelial dysfunction → capillary leak. Severe feature: facial + hand edema, rapid weight gain.', 'MOST IMPORTANT cause of pathological edema; life-threatening'],
        ['Gestational hypertension', 'BP ≥140/90 after 20 wks WITHOUT proteinuria. Edema may be present.', 'May evolve to pre-eclampsia'],
        ['Deep Vein Thrombosis (DVT)', 'Unilateral leg edema, pain, warmth, erythema. Hypercoagulable state of pregnancy ↑ risk 5-10x. Confirm with USS Doppler.', 'Risk of pulmonary embolism'],
        ['Cardiac failure', 'Bilateral edema, dyspnoea, orthopnoea, PND. Peripartum cardiomyopathy occurs in last month or first 5 months postpartum.', 'Echo + BNP to diagnose'],
        ['Nephrotic syndrome / CKD', 'Massive proteinuria → ↓↓ albumin → severe generalized edema (anasarca). Underlying glomerulonephritis, diabetic nephropathy.', 'Proteinuria + hypoalbuminaemia'],
        ['Hypoalbuminaemia', 'Severe malnutrition, liver disease, protein-losing enteropathy → ↓ oncotic pressure → generalised edema.', 'Serum albumin <2 g/dL'],
        ['Hypothyroidism (myxedema)', 'Non-pitting edema (deposition of hyaluronic acid). TSH elevated. May be unmasked or worsen in pregnancy.', 'Non-pitting; check TFTs'],
        ['Acute fatty liver of pregnancy', 'Rare; 3rd trimester. Liver failure → hypoalbuminaemia + coagulopathy → edema + ascites.', 'Medical emergency'],
        ['Pulmonary edema', 'Tocolytic drugs (β2 agonists), fluid overload, pre-eclampsia, mitral stenosis. Dyspnoea, crackles, hypoxia.', 'Pulmonary edema specifically'],
    ], 'Cause', 'Mechanism / Features', 'Key Point'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('5.4 Pre-eclampsia — Detailed Pathophysiology of Edema', heading_style))
    story.append(divider(C_SKY))
    story.append(two_col_table([
        ['Step 1', 'Abnormal trophoblast invasion of spiral arteries (shallow invasion)'],
        ['Step 2', 'Persistent vasoconstriction of spiral arteries → placental ischaemia/hypoxia'],
        ['Step 3', 'Placenta releases anti-angiogenic factors: ↑ sFlt-1 (soluble fms-like tyrosine kinase-1) + ↑ sEng (soluble endoglin)'],
        ['Step 4', 'sFlt-1 binds and inactivates VEGF + PlGF → systemic endothelial dysfunction'],
        ['Step 5', 'Endothelial dysfunction → ↑ capillary permeability → protein-rich fluid leaks into interstitium → EDEMA'],
        ['Step 6', 'Concurrent: renal endothelial damage → proteinuria; cerebral edema → headache/seizures (eclampsia); hepatic edema → RUQ pain'],
        ['Bedside signs', 'Sudden facial/hand edema, rapid weight gain (>1 kg/week), BP ≥140/90, proteinuria ≥2+ on dipstick'],
    ], 'Step', 'Mechanism'))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('5.5 Red Flags — When Edema is Pathological', heading_style))
    story.append(divider(C_SKY))
    story.append(info_box(
        '<b>Red Flags Requiring Urgent Evaluation:</b><br/>'
        '• Facial or periorbital edema (non-dependent = suspect pre-eclampsia)<br/>'
        '• Hand or upper limb edema<br/>'
        '• Pitting edema above the knee<br/>'
        '• Sudden / rapid onset edema<br/>'
        '• Unilateral leg edema (suspect DVT)<br/>'
        '• Edema + hypertension (BP ≥140/90 mmHg)<br/>'
        '• Edema + proteinuria ≥300 mg/24 hours<br/>'
        '• Edema + symptoms: headache, visual disturbance, epigastric/RUQ pain, oliguria<br/>'
        '• Edema + dyspnoea, orthopnoea (suspect cardiac failure)<br/>'
        '• Non-pitting edema (suspect hypothyroidism/myxedema)',
        bgcolor=C_PINK, fgcolor=C_RED))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('5.6 Investigation of Edema in Pregnancy', heading_style))
    story.append(divider(C_SKY))
    story.append(two_col_table([
        ['BP measurement', 'Exclude hypertension; pre-eclampsia, gestational HTN'],
        ['Urine dipstick / 24h protein', 'Proteinuria → pre-eclampsia, nephrotic syndrome'],
        ['Serum albumin', 'Hypoalbuminaemia → nephrotic, liver disease, malnutrition'],
        ['FBC + blood film', 'Anaemia, thrombocytopenia in pre-eclampsia (HELLP)'],
        ['LFTs + uric acid', 'Elevated in pre-eclampsia; uric acid >350 μmol/L significant'],
        ['Renal function (Cr, urea)', 'Creatinine normally low in pregnancy; rise suggests renal impairment'],
        ['TFTs (TSH, free T4)', 'Screen for hypothyroidism if non-pitting edema'],
        ['Doppler USS lower limbs', 'Exclude DVT if unilateral edema'],
        ['Echocardiography', 'If cardiac failure suspected; also useful in pre-eclampsia complications'],
        ['BNP / NT-proBNP', 'BNP >111 pg/mL has positive LR 2.5 for heart failure in pregnancy'],
    ], 'Investigation', 'Purpose'))

    story.append(Spacer(1, 0.3*cm))

    # Edema flowchart
    story.append(Paragraph('Figure 6: Causes of Edema in Pregnancy — Pathophysiology Flowchart', subh_style))
    buf6 = draw_edema_flowchart()
    img6 = RLImage(buf6, width=W-4.5*cm, height=8*cm)
    story.append(img6)
    story.append(Paragraph(
        'Figure 6: Classification and pathophysiology of edema in pregnancy. '
        'Physiological causes are distinguished from pathological causes with '
        'pre-eclampsia highlighted as the most important pathological cause. '
        'Red flags are listed at the bottom. Source: Harrison\'s Principles of Internal Medicine 22e; '
        'Creasy & Resnik\'s Maternal-Fetal Medicine', caption_style))

    story.append(PageBreak())

    # ── QUICK REVISION SUMMARY ─────────────────────────────────────────────────
    story.append(banner('QUICK REVISION SUMMARY — ALL TOPICS', part_style, C_NAVY))
    story.append(Spacer(1, 0.3*cm))

    summary_data = [
        ['Topic', 'Key Points to Remember', 'Exam Tip'],
        ['Hemodynamic Changes\n(★★★★★)',
         '• CO +30-50% (peaks wk 28-34)\n• HR +10-15 bpm\n• SV +40% (peaks wk 28-31)\n• SVR -30-50%\n• BP falls 5-10 mmHg (nadir 2nd trim)\n• Plasma vol +40-50%; physiological anaemia',
         'Know the ORDER of changes: SV drives early CO increase; HR takes over in 3rd trimester. Quote exact percentages.'],
        ['Cardiovascular Changes\n(★★★)',
         '• Flow murmur is normal\n• S3 is normal\n• Diastolic murmur is ALWAYS pathological\n• Supine hypotension - treat with left lateral tilt\n• Hypercoagulable state → DVT/PE risk',
         'Distinguish normal cardiac findings from pathological ones. ECG: left axis deviation, sinus tachycardia.'],
        ['Skin Changes\n(★★★)',
         '• Hyperpigmentation ≥90%\n• Melasma 70% (mask of pregnancy)\n• Linea nigra\n• Striae 50-80%\n• Spider naevi, palmar erythema\n• Telogen effluvium - POSTPARTUM',
         'Remember: hair loss (telogen effluvium) is POSTPARTUM, not during pregnancy. Melasma ≠ chloasma (chloasma is pregnancy-specific term).'],
        ['Breast Changes\n(★★★)',
         '• Ductal proliferation (E) in 1st trim\n• Lobular dev (P) in 2nd trim\n• Colostrum from 16 wks\n• Milk inhibited by E+P during pregnancy\n• Areolae darken, Montgomery glands ↑',
         'Sequence: estrogen → ducts; progesterone → lobules; prolactin → milk (inhibited by E+P in pregnancy). All 3 needed for lactation.'],
        ['Causes of Edema\n(★★★★★)',
         '• Physiological: 80% - dependent, bilateral, pitting\n• Pre-eclampsia: BP + proteinuria\n• DVT: unilateral\n• Cardiac failure: dyspnoea\n• Hypothyroid: non-pitting\n• Red flags: facial, hand, upper limb edema',
         'Pre-eclampsia = most important pathological cause. Always check BP + urine protein. Abnormal if facial/hand edema, non-dependent, or unilateral.'],
    ]

    col_widths = [3*cm, 7.5*cm, 5*cm]
    sum_tbl = Table(summary_data, colWidths=col_widths)
    sum_tbl.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), C_NAVY),
        ('TEXTCOLOR',  (0,0), (-1,0), white),
        ('FONTNAME',   (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE',   (0,0), (-1,0), 9.5),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [C_LIGHT, C_GREY]),
        ('FONTSIZE',   (0,1), (-1,-1), 8.5),
        ('TOPPADDING',    (0,0), (-1,-1), 7),
        ('BOTTOMPADDING', (0,0), (-1,-1), 7),
        ('LEFTPADDING',   (0,0), (-1,-1), 8),
        ('RIGHTPADDING',  (0,0), (-1,-1), 8),
        ('GRID', (0,0), (-1,-1), 0.5, HexColor('#BDC3C7')),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
        ('TEXTCOLOR', (0,1), (0,-1), C_NAVY),
    ]))
    story.append(sum_tbl)
    story.append(Spacer(1, 0.4*cm))
    story.append(divider(C_GOLD))
    story.append(Paragraph(
        '<i>Generated by Orris Medical AI | Sources: Fuster &amp; Hurst\'s The Heart 15e, '
        'Braunwald\'s Heart Disease, Creasy &amp; Resnik\'s Maternal-Fetal Medicine, '
        'Fitzpatrick\'s Dermatology, Current Surgical Therapy 14e, '
        'Harrison\'s Principles of Internal Medicine 22e</i>',
        make_style('Footer', parent='Body', fontSize=7.5, textColor=C_DGREY,
                   alignment=TA_CENTER)))

    # ── BUILD ──────────────────────────────────────────────────────────────────
    doc.build(story)
    print(f"PDF generated: {OUTPUT_PDF}")
    return OUTPUT_PDF

if __name__ == '__main__':
    build_document()
Running Command

cd /home/daytona/workspace/pregnancy-saq && python3 generate_pdf.py 2>&1

Editing File

~/pregnancy-saq/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/pregnancy-saq/generate_pdf.py'
Running Command

cd /home/daytona/workspace/pregnancy-saq && python3 -c "from reportlab.lib.styles import getSampleStyleSheet; s=getSampleStyleSheet(); print(list(s.byName.keys()))"

Running Command

cd /home/daytona/workspace/pregnancy-saq && sed -i "s/parent='Body'/parent='BodyText'/g" generate_pdf.py && python3 generate_pdf.py 2>&1

Running Command

cd /home/daytona/workspace/pregnancy-saq && python3 -c " content = open('generate_pdf.py').read() content = content.replace(\"parent='Body'\", \"parent='BodyText'\") open('generate_pdf.py', 'w').write(content) print('done') " && python3 generate_pdf.py 2>&1

Editing File

~/pregnancy-saq/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/pregnancy-saq/generate_pdf.py'
Running Command

cd /home/daytona/workspace/pregnancy-saq && python3 generate_pdf.py 2>&1

Running Command

cd /home/daytona/workspace/pregnancy-saq && python3 -c " content = open('generate_pdf.py').read() # Fix the red flags box - positional ec arg problem old = \" 'RED FLAGS: Sudden/severe facial edema | Pitting edema above knee | BP >= 140/90 | Proteinuria | Oliguria | Headache / Visual changes',\n '#FDEDEC', '#C0392B', fs=8.5, tc='#922B21', ec='#C0392B')\" # just find and fix the line import re content = content.replace( \" '#FDEDEC', '#C0392B', fs=8.5, tc='#922B21', ec='#C0392B')\", \" '#FDEDEC', fs=8.5, tc='#922B21', ec='#C0392B')\" ) open('generate_pdf.py', 'w').write(content) print('fixed') " && python3 generate_pdf.py 2>&1

Your PDF is ready for download:

Pregnancy SAQ VSAQ

PDF Document · PDF


What's Inside the PDF

The document is a university-level exam answer guide with full answers, tables, and 6 original diagrams/flowcharts sourced from major textbooks:
TopicStarsContent
Hemodynamic Changes in Normal Pregnancy★★★★★Plasma vol, CO, HR, SV, SVR, BP changes with exact values + Timeline + 2 Figures
Cardiovascular Changes in Pregnancy★★★Structural, clinical, venous changes; normal vs pathological findings; trimester table
Skin Changes in Pregnancy★★★Pigmentary, vascular, connective tissue, hair/nails, specific dermatoses with management
Breast Changes in Pregnancy★★★Hormonal cascade, anatomy by trimester, visible changes, postlactational involution
Causes of Edema in Pregnancy★★★★★Starling's forces, physiological vs pathological, pre-eclampsia pathophysiology, red flags, investigations

Diagrams Included:

  1. Hemodynamic Flowchart - Hormone triggers → plasma volume/SVR/HR → CO → labour spike
  2. CO/HR/SV Timeline Graph - % change across gestational weeks with annotations
  3. Cardiovascular Adaptation Diagram - Structural heart changes + BP by trimester bar chart
  4. Skin Changes Mind Map - All 4 categories (pigmentary, vascular, connective tissue, hair/nails)
  5. Breast Changes Timeline - Trimester-by-trimester hormonal drivers and structural changes
  6. Edema Causes Flowchart - Physiological vs pathological causes, pre-eclampsia mechanism, red flags
Sources: Fuster & Hurst's The Heart 15e, Braunwald's Heart Disease, Creasy & Resnik's Maternal-Fetal Medicine, Fitzpatrick's Dermatology, Current Surgical Therapy 14e, Harrison's Principles of Internal Medicine 22e

Create a pdf of physiology of menstruation and ovarian cycle with graps in flowcharts and diagrams for University proffs

Finding Sources
Finding Sources
Finding Sources
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
This is a shared conversation. Sign in to Orris to start your own chat.