Why is tackycardia common in pregnacy

Reading File
Finding Sources
Finding Sources
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Here is a thorough explanation of why tachycardia is common in pregnancy, drawn from authoritative textbooks:

Why Tachycardia is Common in Pregnancy

Tachycardia during pregnancy is a normal physiological adaptation, not a pathological finding in most cases. The heart rate typically rises by 10-20 beats per minute above pre-pregnancy baseline, peaking around 20 weeks' gestation. Here is why this happens:

1. Massive Increase in Demand - The Core Reason

The body needs to deliver far more oxygen and nutrients to:
  • The growing fetus
  • The placenta (which acts as a low-resistance shunt in the circulation)
  • Expanded maternal tissues
This creates a huge increase in cardiac output (CO), which increases 30-50% above baseline by weeks 25-32. Since CO = Heart Rate x Stroke Volume, the heart achieves this by increasing both - and a faster heart rate is a key part of that equation.
  • Braunwald's Heart Disease - p. 1062
  • Campbell Walsh Wein Urology - p. 2583

2. Drop in Systemic Vascular Resistance (SVR)

Early in pregnancy, even before the uteroplacental circulation is fully established, there is a significant drop in SVR caused by:
  • The placenta acting as a low-resistance vascular bed
  • Progesterone and prostacyclin causing smooth muscle relaxation and widespread vasodilation
This drop in SVR lowers blood pressure slightly (by ~5-10 mmHg in the second trimester). The body compensates reflexively by activating the sympathetic nervous system, which drives the heart rate up.
  • Campbell Walsh Wein Urology - p. 2583

3. Plasma Volume Expansion

Blood (plasma) volume increases by approximately 40% (about 2 litres) during pregnancy. This volume expansion stretches the heart chambers. According to the Frank-Starling mechanism, this increases stroke volume - but the heart also beats faster to handle the added volume load.
  • Murray & Nadel's Respiratory Medicine - p. 2043

4. Sympathetic Nervous System Activation

The sympathetic nervous system is upregulated throughout pregnancy. Sympathetic activity drives the heart rate up directly via beta-1 adrenoceptors. This sympathetic surge accounts for up to a 30% increase in maternal heart rate, reaching its maximum around 20 weeks.
  • Campbell Walsh Wein Urology - p. 2583

5. Progesterone Effects

Progesterone rises dramatically throughout pregnancy. Beyond causing vasodilation, progesterone also acts on the central nervous system and autonomic tone, contributing to the increased resting heart rate as well as the sensation of breathlessness (dyspnea) that many pregnant women feel.

Summary Table

MechanismEffect on Heart Rate
Low-resistance placenta + progesterone vasodilationReflex sympathetic tachycardia
Sympathetic nervous system activationDirect increase via beta-1 receptors
40% plasma volume expansionIncreased preload → increased CO demand
Higher metabolic demand (fetus + placenta)Need for greater cardiac output
Progesterone on autonomic toneContributes to elevated baseline HR

When to Worry

While a modest increase in heart rate is normal, a heart rate above 100 bpm at rest (true tachycardia) should prompt investigation for:
  • Anaemia (very common in pregnancy due to dilutional effect)
  • Thyroid disease (hyperthyroidism)
  • Pulmonary embolism
  • Infection/sepsis
  • Dehydration
  • Arrhythmias (atrial fibrillation, SVT) - especially in women with pre-existing heart disease
The increased heart rate and blood volume of normal pregnancy also worsens pre-existing heart conditions like mitral stenosis, which can precipitate pulmonary oedema during pregnancy.
  • Harrison's Principles of Internal Medicine 22E - p. 328

Create a clinical summary document on cardiovascular changes in pregnancy

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

mkdir -p /home/daytona/workspace/cv-pregnancy && ls /home/daytona/workspace/cv-p…

Writing File

~/cv-pregnancy/generate_pdf.py

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

OUTPUT = "/home/daytona/workspace/cv-pregnancy/CV_Changes_in_Pregnancy.pdf"

# --- Colour palette ---
DEEP_BLUE   = HexColor("#1B3A6B")
MID_BLUE    = HexColor("#2E6DA4")
LIGHT_BLUE  = HexColor("#D6E8F7")
ACCENT_TEAL = HexColor("#1A7F8E")
WARN_AMBER  = HexColor("#D97706")
WARN_BG     = HexColor("#FEF3C7")
TABLE_ALT   = HexColor("#EAF4FB")
BORDER_GREY = HexColor("#CBD5E1")
BODY_GREY   = HexColor("#374151")
LIGHT_GREY  = HexColor("#F8FAFC")

W, H = A4

# ─── Page template with header / footer ─────────────────────────────────────
class HeaderFooterCanvas(canvas.Canvas):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._saved_page_states = []

    def showPage(self):
        self._saved_page_states.append(dict(self.__dict__))
        self._startPage()

    def save(self):
        num_pages = len(self._saved_page_states)
        for state in self._saved_page_states:
            self.__dict__.update(state)
            self.draw_header_footer(num_pages)
            super().showPage()
        super().save()

    def draw_header_footer(self, page_count):
        page_num = self._saved_page_states.index(dict(self.__dict__)) + 1 \
            if dict(self.__dict__) in self._saved_page_states else self._pageNumber

        # Header bar
        self.setFillColor(DEEP_BLUE)
        self.rect(0, H - 1.5*cm, W, 1.5*cm, fill=1, stroke=0)
        self.setFillColor(white)
        self.setFont("Helvetica-Bold", 11)
        self.drawString(1.5*cm, H - 0.95*cm, "Cardiovascular Changes in Pregnancy")
        self.setFont("Helvetica", 8)
        self.drawRightString(W - 1.5*cm, H - 0.95*cm, "Clinical Summary for Medical Students")

        # Accent line under header
        self.setStrokeColor(ACCENT_TEAL)
        self.setLineWidth(2)
        self.line(0, H - 1.55*cm, W, H - 1.55*cm)

        # Footer
        self.setStrokeColor(BORDER_GREY)
        self.setLineWidth(0.5)
        self.line(1.2*cm, 1.3*cm, W - 1.2*cm, 1.3*cm)
        self.setFillColor(BODY_GREY)
        self.setFont("Helvetica", 7.5)
        self.drawString(1.5*cm, 0.75*cm,
            "Sources: Braunwald's Heart Disease | Fuster & Hurst's The Heart | Barash Clinical Anesthesia | Campbell Walsh Urology | Murray & Nadel's Respiratory Medicine")
        self.drawRightString(W - 1.5*cm, 0.75*cm, f"Page {self._pageNumber} of {page_count}")


# ─── Build styles ─────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

title_style = ParagraphStyle(
    "Title", fontName="Helvetica-Bold", fontSize=22,
    textColor=white, alignment=TA_CENTER, spaceAfter=4
)
subtitle_style = ParagraphStyle(
    "Subtitle", fontName="Helvetica", fontSize=11,
    textColor=HexColor("#BFD9F0"), alignment=TA_CENTER, spaceAfter=0
)
h1_style = ParagraphStyle(
    "H1", fontName="Helvetica-Bold", fontSize=13,
    textColor=white, spaceAfter=6, spaceBefore=4,
    leftIndent=0, borderPad=4
)
h2_style = ParagraphStyle(
    "H2", fontName="Helvetica-Bold", fontSize=11,
    textColor=DEEP_BLUE, spaceAfter=4, spaceBefore=10,
    borderColor=DEEP_BLUE
)
body_style = ParagraphStyle(
    "Body", fontName="Helvetica", fontSize=9.5,
    textColor=BODY_GREY, leading=14, spaceAfter=5,
    alignment=TA_JUSTIFY
)
bullet_style = ParagraphStyle(
    "Bullet", fontName="Helvetica", fontSize=9.5,
    textColor=BODY_GREY, leading=14, spaceAfter=3,
    leftIndent=14, bulletIndent=4
)
small_style = ParagraphStyle(
    "Small", fontName="Helvetica-Oblique", fontSize=8,
    textColor=HexColor("#6B7280"), leading=11, spaceAfter=4,
    alignment=TA_CENTER
)
callout_style = ParagraphStyle(
    "Callout", fontName="Helvetica-Bold", fontSize=9.5,
    textColor=HexColor("#92400E"), leading=13, spaceAfter=2
)
callout_body_style = ParagraphStyle(
    "CalloutBody", fontName="Helvetica", fontSize=9,
    textColor=HexColor("#78350F"), leading=13, spaceAfter=3,
    leftIndent=8
)
warn_style = ParagraphStyle(
    "Warn", fontName="Helvetica-Bold", fontSize=9.5,
    textColor=HexColor("#991B1B"), leading=13, spaceAfter=2
)


# ─── Helper: section header band ──────────────────────────────────────────────
def section_header(text, color=DEEP_BLUE):
    data = [[Paragraph(text, h1_style)]]
    t = Table(data, colWidths=[W - 3.4*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, -1), color),
        ("ROWBACKGROUNDS", (0, 0), (-1, -1), [color]),
        ("TOPPADDING", (0, 0), (-1, -1), 6),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 6),
        ("LEFTPADDING", (0, 0), (-1, -1), 10),
        ("RIGHTPADDING", (0, 0), (-1, -1), 6),
        ("ROUNDEDCORNERS", [4, 4, 4, 4]),
    ]))
    return t


def callout_box(title, items, bg=WARN_BG, border=WARN_AMBER):
    content = [Paragraph(title, callout_style)]
    for item in items:
        content.append(Paragraph(f"• {item}", callout_body_style))
    data = [[content]]
    t = Table(data, colWidths=[W - 3.4*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, -1), bg),
        ("BOX", (0, 0), (-1, -1), 1.5, border),
        ("LEFTPADDING", (0, 0), (-1, -1), 10),
        ("RIGHTPADDING", (0, 0), (-1, -1), 8),
        ("TOPPADDING", (0, 0), (-1, -1), 7),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 7),
        ("ROUNDEDCORNERS", [4, 4, 4, 4]),
    ]))
    return t


# ─── Document setup ───────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT, pagesize=A4,
    leftMargin=1.7*cm, rightMargin=1.7*cm,
    topMargin=2.2*cm, bottomMargin=1.8*cm,
    title="Cardiovascular Changes in Pregnancy",
    author="Orris Medical"
)

story = []

# ══════════════════════════════════════════════════════════════════════
# COVER / TITLE BLOCK
# ══════════════════════════════════════════════════════════════════════
cover_text = [
    [Paragraph("Cardiovascular Changes in Pregnancy", title_style)],
    [Paragraph("A Clinical Summary for Medical Students", subtitle_style)],
    [Paragraph("July 2026  |  Compiled from Braunwald's Heart Disease, Fuster & Hurst's The Heart,<br/>"
               "Barash Clinical Anesthesia, Campbell Walsh Urology, Murray & Nadel's Respiratory Medicine",
               small_style)]
]
cover = Table(cover_text, colWidths=[W - 3.4*cm])
cover.setStyle(TableStyle([
    ("BACKGROUND", (0, 0), (-1, -1), DEEP_BLUE),
    ("TOPPADDING", (0, 0), (-1, 0), 20),
    ("BOTTOMPADDING", (0, 0), (-1, 0), 4),
    ("TOPPADDING", (0, 1), (-1, 1), 2),
    ("BOTTOMPADDING", (0, 1), (-1, 1), 4),
    ("TOPPADDING", (0, 2), (-1, 2), 6),
    ("BOTTOMPADDING", (0, 2), (-1, 2), 20),
    ("LEFTPADDING", (0, 0), (-1, -1), 16),
    ("RIGHTPADDING", (0, 0), (-1, -1), 16),
]))
story.append(cover)
story.append(Spacer(1, 0.4*cm))

# ══════════════════════════════════════════════════════════════════════
# 1. OVERVIEW
# ══════════════════════════════════════════════════════════════════════
story.append(section_header("1.  Overview"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
    "Pregnancy induces profound but reversible cardiovascular adaptations that begin as early as "
    "<b>6 weeks of gestation</b> and reach their peak around <b>25-32 weeks</b>. These changes are "
    "designed to meet the increased metabolic demands of the mother, fetus, and placenta. "
    "In women with normal hearts they are well tolerated; however, in women with pre-existing heart "
    "disease they can precipitate decompensation and cardiac complications.",
    body_style
))
story.append(Spacer(1, 0.3*cm))

# ══════════════════════════════════════════════════════════════════════
# 2. KEY HAEMODYNAMIC CHANGES TABLE
# ══════════════════════════════════════════════════════════════════════
story.append(section_header("2.  Key Haemodynamic Changes at a Glance", color=MID_BLUE))
story.append(Spacer(1, 0.2*cm))

hd_headers = ["Parameter", "Change", "Magnitude / Timing", "Clinical Significance"]
hd_data = [
    hd_headers,
    ["Heart Rate (HR)", "↑ Increase", "+10-20 bpm; peaks ~20 wks", "Physiological tachycardia; worsens mitral stenosis"],
    ["Stroke Volume (SV)", "↑ Increase", "+20-50%", "Main driver of CO rise in early pregnancy"],
    ["Cardiac Output (CO)", "↑ Increase", "+30-50%; peaks 25-32 wks", "Further ↑ 60-80% during labour"],
    ["Systemic Vascular\nResistance (SVR)", "↓ Decrease", "-20-50%; from 8 wks", "Driven by progesterone, prostacyclin, placenta"],
    ["Blood Pressure (BP)", "↓ then normal", "Falls 5-10 mmHg; returns\nto baseline in 3rd trimester", "Widened pulse pressure; postural hypotension risk"],
    ["Plasma Volume", "↑ Increase", "+40-50% (~2 L)", "Physiological anaemia; dilutional effect"],
    ["Red Cell Mass", "↑ Increase", "+20-30%", "Less than plasma rise → Hb may fall to 11 g/dL"],
    ["Pulmonary Vascular\nResistance (PVR)", "↓ Decrease", "Parallel to SVR", "Risk if pre-existing pulmonary hypertension"],
    ["CVP / PCWP", "Unchanged", "Stable throughout", "Reflects ↑ LV compliance"],
    ["Uterine Blood Flow", "↑ Increase", "50-100 → 700-900 mL/min\nby term", "Vital for fetal oxygenation"],
    ["Renal Blood Flow", "↑ Increase", "+60%; GFR +40-50%", "Adjust drug doses; ↑ creatinine clearance"],
]

col_widths = [3.5*cm, 2.3*cm, 4.7*cm, 6.2*cm]
hd_table = Table(hd_data, colWidths=col_widths, repeatRows=1)
hd_style = TableStyle([
    # Header row
    ("BACKGROUND",    (0, 0), (-1, 0), DEEP_BLUE),
    ("TEXTCOLOR",     (0, 0), (-1, 0), white),
    ("FONTNAME",      (0, 0), (-1, 0), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 0), (-1, 0), 9),
    ("ALIGN",         (0, 0), (-1, 0), "CENTER"),
    ("VALIGN",        (0, 0), (-1, -1), "MIDDLE"),
    # Alternating rows
    ("ROWBACKGROUNDS", (0, 1), (-1, -1), [white, TABLE_ALT]),
    ("FONTNAME",      (0, 1), (-1, -1), "Helvetica"),
    ("FONTSIZE",      (0, 1), (-1, -1), 8.5),
    ("TEXTCOLOR",     (0, 1), (-1, -1), BODY_GREY),
    # Highlight change column
    ("FONTNAME",      (1, 1), (1, -1), "Helvetica-Bold"),
    # Grid
    ("GRID",          (0, 0), (-1, -1), 0.4, BORDER_GREY),
    ("LINEBELOW",     (0, 0), (-1, 0), 1.5, white),
    # Padding
    ("TOPPADDING",    (0, 0), (-1, -1), 5),
    ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
    ("LEFTPADDING",   (0, 0), (-1, -1), 6),
    ("RIGHTPADDING",  (0, 0), (-1, -1), 6),
])
hd_table.setStyle(hd_style)
story.append(hd_table)
story.append(Paragraph(
    "CO = cardiac output; CVP = central venous pressure; GFR = glomerular filtration rate; "
    "LV = left ventricle; PCWP = pulmonary capillary wedge pressure; SVR = systemic vascular resistance.",
    small_style
))
story.append(Spacer(1, 0.4*cm))

# ══════════════════════════════════════════════════════════════════════
# 3. MECHANISMS
# ══════════════════════════════════════════════════════════════════════
story.append(section_header("3.  Mechanisms Driving Cardiovascular Adaptation"))
story.append(Spacer(1, 0.2*cm))

mech_data = [
    ["Mechanism", "Details"],
    ["Low-resistance placenta",
     "Placenta acts as an arteriovenous shunt, reducing SVR from early gestation before "
     "uteroplacental circulation is fully established."],
    ["Progesterone & prostacyclin",
     "Smooth muscle relaxation causes widespread peripheral vasodilation, reducing SVR "
     "by 20-50%. Progesterone also drives minute ventilation (dyspnoea of pregnancy)."],
    ["Renin-Angiotensin-\nAldosterone System",
     "Activated early in pregnancy, promoting sodium and water retention, expanding plasma "
     "volume by ~2 L (40-50%)."],
    ["Sympathetic activation",
     "Reflex response to reduced SVR. Up to a 30% increase in heart rate via beta-1 "
     "adrenoceptors, peaking around 20 weeks' gestation."],
    ["Frank-Starling mechanism",
     "Expanded blood volume stretches ventricular walls, increasing stroke volume by 20-50%. "
     "Left ventricular end-diastolic volume is increased; ejection fraction is little changed."],
    ["Relaxin & oestrogen",
     "Relaxin promotes vasodilation and increases glomerular filtration. Oestrogen, volume "
     "overload, and increased cardiac demand cause reversible LV hypertrophy (~50% increase "
     "in mass at term) and mild diastolic dysfunction."],
]

mech_col_widths = [4.2*cm, 12.5*cm]
mech_table = Table(mech_data, colWidths=mech_col_widths, repeatRows=1)
mech_table.setStyle(TableStyle([
    ("BACKGROUND",    (0, 0), (-1, 0), ACCENT_TEAL),
    ("TEXTCOLOR",     (0, 0), (-1, 0), white),
    ("FONTNAME",      (0, 0), (-1, 0), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 0), (-1, 0), 9),
    ("ROWBACKGROUNDS", (0, 1), (-1, -1), [white, TABLE_ALT]),
    ("FONTNAME",      (0, 1), (0, -1), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 1), (-1, -1), 8.5),
    ("TEXTCOLOR",     (0, 1), (-1, -1), BODY_GREY),
    ("TEXTCOLOR",     (0, 1), (0, -1), DEEP_BLUE),
    ("VALIGN",        (0, 0), (-1, -1), "TOP"),
    ("GRID",          (0, 0), (-1, -1), 0.4, BORDER_GREY),
    ("TOPPADDING",    (0, 0), (-1, -1), 6),
    ("BOTTOMPADDING", (0, 0), (-1, -1), 6),
    ("LEFTPADDING",   (0, 0), (-1, -1), 7),
    ("RIGHTPADDING",  (0, 0), (-1, -1), 7),
]))
story.append(mech_table)
story.append(Spacer(1, 0.4*cm))

# ══════════════════════════════════════════════════════════════════════
# 4. TRIMESTER-BY-TRIMESTER
# ══════════════════════════════════════════════════════════════════════
story.append(section_header("4.  Trimester-by-Trimester Timeline", color=MID_BLUE))
story.append(Spacer(1, 0.2*cm))

tri_data = [
    ["Stage", "Key Cardiovascular Events"],
    ["Weeks 6-12\n(1st Trimester)",
     "• Plasma volume begins to expand\n"
     "• SVR starts to fall (progesterone, prostacyclin)\n"
     "• Heart rate starts rising\n"
     "• CO begins to increase; BP falls 5-10 mmHg\n"
     "• Early LV remodelling begins"],
    ["Weeks 13-28\n(2nd Trimester)",
     "• CO peaks progressively toward 25-32 wks (+30-50%)\n"
     "• HR increase peaks ~20 wks (+10-20 bpm)\n"
     "• BP nadir (lowest point)\n"
     "• Plasma volume expansion maximal (~32 wks)\n"
     "• Physiological anaemia most evident at 32-34 wks\n"
     "• LV mass increases ~50%; mild diastolic dysfunction"],
    ["Weeks 29-40\n(3rd Trimester)",
     "• BP gradually returns toward pre-pregnancy baseline\n"
     "• SVR begins to recover slightly\n"
     "• Gravid uterus compresses IVC in supine position\n"
     "  → Supine hypotensive syndrome (venous return ↓, CO ↓ 25%)\n"
     "• Uterine blood flow reaches 700-900 mL/min at term"],
    ["Labour &\nDelivery",
     "• CO rises a further 60-80% during active labour\n"
     "• Each uterine contraction autotransfuses 300-500 mL\n"
     "• Catecholamines from pain/anxiety increase HR and BP\n"
     "• Immediately postpartum: IVC compression relieved → surge in venous return"],
    ["Postpartum\n(0-6 months)",
     "• Haemodynamic changes resolve within 2 weeks\n"
     "• Complete normalisation may take up to 6 months\n"
     "• Risk of heart failure in first week (fluid mobilisation)\n"
     "• Plasma volume falls sharply after delivery"],
]

tri_col_widths = [3.5*cm, 13.2*cm]
tri_table = Table(tri_data, colWidths=tri_col_widths, repeatRows=1)
tri_table.setStyle(TableStyle([
    ("BACKGROUND",    (0, 0), (-1, 0), DEEP_BLUE),
    ("TEXTCOLOR",     (0, 0), (-1, 0), white),
    ("FONTNAME",      (0, 0), (-1, 0), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 0), (-1, 0), 9),
    ("ROWBACKGROUNDS", (0, 1), (-1, -1), [white, TABLE_ALT]),
    ("FONTNAME",      (0, 1), (0, -1), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 1), (-1, -1), 8.5),
    ("TEXTCOLOR",     (0, 1), (0, -1), ACCENT_TEAL),
    ("TEXTCOLOR",     (1, 1), (1, -1), BODY_GREY),
    ("VALIGN",        (0, 0), (-1, -1), "TOP"),
    ("ALIGN",         (0, 0), (0, -1), "CENTER"),
    ("GRID",          (0, 0), (-1, -1), 0.4, BORDER_GREY),
    ("TOPPADDING",    (0, 0), (-1, -1), 7),
    ("BOTTOMPADDING", (0, 0), (-1, -1), 7),
    ("LEFTPADDING",   (0, 0), (-1, -1), 7),
    ("RIGHTPADDING",  (0, 0), (-1, -1), 7),
]))
story.append(tri_table)
story.append(Spacer(1, 0.4*cm))

# ══════════════════════════════════════════════════════════════════════
# 5. CARDIAC EXAMINATION IN NORMAL PREGNANCY
# ══════════════════════════════════════════════════════════════════════
story.append(section_header("5.  Cardiac Examination Findings in Normal Pregnancy"))
story.append(Spacer(1, 0.2*cm))

exam_data = [
    ["Finding", "Expected (Normal)", "Abnormal - Warrants Investigation"],
    ["Symptoms", "Fatigue, dyspnoea on exertion, palpitations,\nlight-headedness, ankle oedema (mild)",
     "Angina, resting dyspnoea, PND, syncope,\nsustained palpitations"],
    ["Vital signs", "HR ↑ 10-20 bpm above baseline;\nBP slightly reduced; widened pulse pressure",
     "HR >120 at rest; BP ≥140/90 mmHg\n(hypertensive disorder)"],
    ["Pulse", "Collapsing (bounding) arterial pulse", "Irregularly irregular (AF)"],
    ["JVP", "Prominent pulsations; pressure NOT elevated", "Elevated JVP (heart failure)"],
    ["Apex beat", "Laterally displaced; palpable RV or pulmonary trunk", "Heaving apex (LV hypertrophy)"],
    ["Murmurs", "Soft systolic ejection murmur (pulmonic area /\nleft sternal border) - flow murmur\n"
     "Mammary souffle (benign, 3rd trimester)",
     "Holosystolic murmur, diastolic murmur,\nexaggerated S2 (pulmonary HTN), S4"],
    ["Heart sounds", "S3 may be physiological", "S4 always abnormal"],
    ["ECG", "Sinus tachycardia; left axis deviation;\nshortened PR; Q waves in inferior leads;\nnonspecific ST-T changes; ectopics common",
     "Sustained arrhythmia; bundle branch block;\nsigns of ischaemia"],
    ["Echocardiogram", "↑ LV dimensions; ↑ LV mass; mild\ndiastolic dysfunction; mild MR/TR normal",
     "Systolic dysfunction; severe valvular disease;\ndilated RV; pericardial effusion"],
]

exam_col_widths = [3.2*cm, 7.3*cm, 6.2*cm]
exam_table = Table(exam_data, colWidths=exam_col_widths, repeatRows=1)
exam_table.setStyle(TableStyle([
    ("BACKGROUND",    (0, 0), (-1, 0), ACCENT_TEAL),
    ("TEXTCOLOR",     (0, 0), (-1, 0), white),
    ("FONTNAME",      (0, 0), (-1, 0), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 0), (-1, 0), 9),
    ("ROWBACKGROUNDS", (0, 1), (-1, -1), [white, TABLE_ALT]),
    ("FONTNAME",      (0, 1), (0, -1), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 1), (-1, -1), 8),
    ("TEXTCOLOR",     (0, 1), (0, -1), DEEP_BLUE),
    ("TEXTCOLOR",     (1, 1), (1, -1), BODY_GREY),
    # Red text for abnormal column
    ("TEXTCOLOR",     (2, 1), (2, -1), HexColor("#991B1B")),
    ("FONTNAME",      (2, 1), (2, -1), "Helvetica-Oblique"),
    ("BACKGROUND",    (2, 0), (2, 0), HexColor("#991B1B")),
    ("VALIGN",        (0, 0), (-1, -1), "TOP"),
    ("GRID",          (0, 0), (-1, -1), 0.4, BORDER_GREY),
    ("TOPPADDING",    (0, 0), (-1, -1), 5),
    ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
    ("LEFTPADDING",   (0, 0), (-1, -1), 6),
    ("RIGHTPADDING",  (0, 0), (-1, -1), 6),
]))
story.append(exam_table)
story.append(Paragraph(
    "AF = atrial fibrillation; HTN = hypertension; JVP = jugular venous pressure; LV = left ventricle; "
    "MR = mitral regurgitation; PND = paroxysmal nocturnal dyspnoea; RV = right ventricle; TR = tricuspid regurgitation.",
    small_style
))
story.append(Spacer(1, 0.4*cm))

# ══════════════════════════════════════════════════════════════════════
# 6. SYSTEMIC CHANGES BEYOND THE HEART
# ══════════════════════════════════════════════════════════════════════
story.append(section_header("6.  Systemic Changes: Beyond the Heart", color=MID_BLUE))
story.append(Spacer(1, 0.2*cm))

sys_data = [
    ["System", "Change", "Key Implications"],
    ["Haematology",
     "Plasma volume +50%; RBC mass +20-30%\nPhysiological anaemia (Hb may fall to 11 g/dL)\nCoagulation factors ↑; Protein S ↓; fibrinolysis ↓",
     "Increased VTE risk\nAnaemia worsens high-output state\nFibrinogen ↑ 400-500 mg/dL (postpartum\nhaemorrhage predictor)"],
    ["Renal",
     "Renal blood flow +60%; GFR +40-50%\nProteinuria mildly ↑; uric acid clearance ↑",
     "Drug dosing adjustment needed\n↑ Proteinuria in preeclampsia\nNormal creatinine may be lower than expected"],
    ["Respiratory",
     "Tidal volume +50% (progesterone)\nMinute ventilation ↑; FRC ↓\nMild respiratory alkalosis (PaCO2 ~30 mmHg)",
     "Rapid desaturation during intubation\nDyspnoea common (normal)\nDifficult airway in late pregnancy"],
    ["Lipid / Metabolic",
     "Triglycerides ↑; total cholesterol +50%\nInsulin resistance ↑; diabetogenic state",
     "Gestational diabetes risk\nExisting dyslipidaemia → adverse outcomes"],
    ["Coagulation",
     "Procoagulant state (↑ factors II, VII, X, XII;\n↑ fibrinogen; ↓ protein S; ↓ fibrinolysis)",
     "DVT / PE risk especially with:\n- Prosthetic heart valves\n- Atrial fibrillation\n- Fontan circulation"],
]

sys_col_widths = [3.0*cm, 7.5*cm, 6.2*cm]
sys_table = Table(sys_data, colWidths=sys_col_widths, repeatRows=1)
sys_table.setStyle(TableStyle([
    ("BACKGROUND",    (0, 0), (-1, 0), DEEP_BLUE),
    ("TEXTCOLOR",     (0, 0), (-1, 0), white),
    ("FONTNAME",      (0, 0), (-1, 0), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 0), (-1, 0), 9),
    ("ROWBACKGROUNDS", (0, 1), (-1, -1), [white, TABLE_ALT]),
    ("FONTNAME",      (0, 1), (0, -1), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 1), (-1, -1), 8),
    ("TEXTCOLOR",     (0, 1), (0, -1), ACCENT_TEAL),
    ("TEXTCOLOR",     (1, 1), (-1, -1), BODY_GREY),
    ("VALIGN",        (0, 0), (-1, -1), "TOP"),
    ("GRID",          (0, 0), (-1, -1), 0.4, BORDER_GREY),
    ("TOPPADDING",    (0, 0), (-1, -1), 6),
    ("BOTTOMPADDING", (0, 0), (-1, -1), 6),
    ("LEFTPADDING",   (0, 0), (-1, -1), 7),
    ("RIGHTPADDING",  (0, 0), (-1, -1), 7),
]))
story.append(sys_table)
story.append(Spacer(1, 0.4*cm))

# ══════════════════════════════════════════════════════════════════════
# 7. CLINICAL IMPLICATIONS / HIGH-RISK CONDITIONS
# ══════════════════════════════════════════════════════════════════════
story.append(section_header("7.  Clinical Implications - High-Risk Cardiac Conditions"))
story.append(Spacer(1, 0.2*cm))

story.append(Paragraph(
    "Pre-existing cardiac disease is the leading cause of indirect maternal death in developed countries. "
    "Pregnancy amplifies haemodynamic stress, making certain conditions particularly dangerous.",
    body_style
))
story.append(Spacer(1, 0.2*cm))

risk_data = [
    ["Condition", "Why Pregnancy is Dangerous", "Risk Category"],
    ["Mitral Stenosis",
     "Fixed obstruction cannot accommodate ↑ CO and HR\n"
     "↑ Transmitral gradient → pulmonary oedema, tachyarrhythmias",
     "HIGH"],
    ["Pulmonary Hypertension\n(incl. Eisenmenger's)",
     "Fixed PVR cannot accommodate ↑ CO\nSVR fall → ↑ R→L shunt; systemic hypoxaemia\nMortality 25-50%",
     "VERY HIGH\n(Contraindicated)"],
    ["Peripartum\nCardiomyopathy",
     "New-onset LV systolic dysfunction in last month of\npregnancy or within 5 months postpartum\nMortality 6-10%",
     "HIGH"],
    ["Hypertrophic\nCardiomyopathy",
     "Outflow obstruction worsened by SVR drop\nVentricular arrhythmia risk ↑",
     "MODERATE-HIGH"],
    ["Aortic Stenosis\n(severe)",
     "Fixed obstruction cannot accommodate ↑ SV demand\nLV failure risk; syncope; sudden death",
     "HIGH"],
    ["Fontan Circulation",
     "Single-ventricle physiology has limited haemodynamic\nreserve; ↑ thromboembolic risk; fetal loss common",
     "HIGH"],
    ["Prosthetic Heart\nValves",
     "Anticoagulation management complex during pregnancy\n↑ Valve thrombosis risk with mechanical valves",
     "HIGH"],
    ["Hypertensive\nDisorders",
     "Chronic HTN, gestational HTN, preeclampsia, eclampsia\n↑ MAP + SVR in preeclampsia (opposite of normal adaptation)",
     "MODERATE-HIGH"],
]

risk_col_widths = [3.6*cm, 9.8*cm, 3.3*cm]
risk_table = Table(risk_data, colWidths=risk_col_widths, repeatRows=1)
risk_table.setStyle(TableStyle([
    ("BACKGROUND",    (0, 0), (-1, 0), DEEP_BLUE),
    ("TEXTCOLOR",     (0, 0), (-1, 0), white),
    ("FONTNAME",      (0, 0), (-1, 0), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 0), (-1, 0), 9),
    ("ROWBACKGROUNDS", (0, 1), (-1, -1), [white, TABLE_ALT]),
    ("FONTNAME",      (0, 1), (0, -1), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 1), (-1, -1), 8),
    ("TEXTCOLOR",     (0, 1), (0, -1), DEEP_BLUE),
    ("TEXTCOLOR",     (1, 1), (1, -1), BODY_GREY),
    ("TEXTCOLOR",     (2, 1), (2, -1), HexColor("#991B1B")),
    ("FONTNAME",      (2, 1), (2, -1), "Helvetica-Bold"),
    ("ALIGN",         (2, 0), (2, -1), "CENTER"),
    ("VALIGN",        (0, 0), (-1, -1), "TOP"),
    ("GRID",          (0, 0), (-1, -1), 0.4, BORDER_GREY),
    ("TOPPADDING",    (0, 0), (-1, -1), 6),
    ("BOTTOMPADDING", (0, 0), (-1, -1), 6),
    ("LEFTPADDING",   (0, 0), (-1, -1), 7),
    ("RIGHTPADDING",  (0, 0), (-1, -1), 7),
]))
story.append(risk_table)
story.append(Spacer(1, 0.4*cm))

# ══════════════════════════════════════════════════════════════════════
# 8. SUPINE HYPOTENSIVE SYNDROME
# ══════════════════════════════════════════════════════════════════════
story.append(section_header("8.  Supine Hypotensive Syndrome (Aortocaval Compression)", color=MID_BLUE))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
    "After ~20 weeks, the gravid uterus can nearly completely compress the inferior vena cava (IVC) "
    "when a woman lies supine. This reduces venous return, dropping preload and causing:",
    body_style
))

supcols = ["Effect", "Consequence"]
supdata = [
    supcols,
    ["IVC compression → ↓ venous return", "↓ Preload → ↓ Stroke Volume"],
    ["↓ Stroke Volume", "CO falls by up to 25-30%"],
    ["Baroreceptor reflex", "Compensatory tachycardia"],
    ["Hypotension", "Nausea, dizziness, altered mental status"],
    ["↓ Uterine perfusion", "Fetal distress / bradycardia"],
    ["Anaesthesia impairs sympathetic compensation", "Severe hypotension, cardiovascular collapse"],
]
suptable = Table(supdata, colWidths=[8.35*cm, 8.35*cm], repeatRows=1)
suptable.setStyle(TableStyle([
    ("BACKGROUND",    (0, 0), (-1, 0), ACCENT_TEAL),
    ("TEXTCOLOR",     (0, 0), (-1, 0), white),
    ("FONTNAME",      (0, 0), (-1, 0), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 0), (-1, 0), 9),
    ("ROWBACKGROUNDS", (0, 1), (-1, -1), [white, TABLE_ALT]),
    ("FONTSIZE",      (0, 1), (-1, -1), 8.5),
    ("FONTNAME",      (0, 1), (0, -1), "Helvetica-Bold"),
    ("TEXTCOLOR",     (0, 1), (0, -1), DEEP_BLUE),
    ("TEXTCOLOR",     (1, 1), (-1, -1), BODY_GREY),
    ("GRID",          (0, 0), (-1, -1), 0.4, BORDER_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),
]))
story.append(suptable)
story.append(Spacer(1, 0.15*cm))
story.append(callout_box(
    "Management of Supine Hypotension",
    [
        "Position: Left lateral decubitus OR 15-20 degree left lateral tilt with wedge after 20 weeks",
        "During surgery: aggressive IV fluid preloading; vasopressors (phenylephrine preferred) ready",
        "Avoid supine and lithotomy positions where possible in late pregnancy",
        "Monitor fetal heart rate intraoperatively",
    ],
    bg=LIGHT_BLUE, border=MID_BLUE
))
story.append(Spacer(1, 0.4*cm))

# ══════════════════════════════════════════════════════════════════════
# 9. RED FLAGS / WHEN TO INVESTIGATE
# ══════════════════════════════════════════════════════════════════════
story.append(section_header("9.  Red Flag Symptoms - When to Investigate"))
story.append(Spacer(1, 0.2*cm))
story.append(callout_box(
    "Symptoms that are NORMAL in Pregnancy (no investigation needed if mild, <20 wks):",
    [
        "Dyspnoea on exertion",
        "Fatigue, light-headedness",
        "Palpitations (especially ectopics)",
        "Mild ankle oedema",
        "Soft systolic ejection murmur",
    ],
    bg=HexColor("#F0FFF4"), border=HexColor("#16A34A")
))
story.append(Spacer(1, 0.2*cm))
story.append(callout_box(
    "RED FLAG Symptoms - Prompt Cardiology Referral / Investigation:",
    [
        "Angina or chest pain at rest",
        "Significant resting dyspnoea or paroxysmal nocturnal dyspnoea (PND)",
        "Syncope or pre-syncope (especially exertional)",
        "Sustained palpitations or documented arrhythmia",
        "Symptoms arising after 20 weeks that are progressive or disabling",
        "Any diastolic murmur or new holosystolic murmur",
        "Exaggerated S2 (pulmonary hypertension)",
        "Cyanosis",
    ],
    bg=WARN_BG, border=WARN_AMBER
))
story.append(Spacer(1, 0.4*cm))

# ══════════════════════════════════════════════════════════════════════
# 10. INVESTIGATION GUIDE
# ══════════════════════════════════════════════════════════════════════
story.append(section_header("10.  Investigations in Pregnancy", color=MID_BLUE))
story.append(Spacer(1, 0.2*cm))

inv_data = [
    ["Investigation", "Use in Pregnancy", "Notes"],
    ["ECG", "Safe; first-line for arrhythmia, ischaemia\nNormal changes: see Section 5", "Sinus tachycardia and ectopics common; LAD normal"],
    ["Echocardiogram (TTE)", "Safe; preferred imaging modality\nFor unexplained symptoms, murmurs, known CVD", "LV dilation and mild MR/TR normal findings"],
    ["Chest X-Ray", "Safe with abdominal shielding\nUse for pulmonary oedema, cardiomegaly", "Cardiac silhouette normally enlarged"],
    ["BNP / NT-proBNP", "BNP >111 pg/mL: LR+ 2.5 for heart failure\nBNP <100 pg/mL: 100% NPV for complications\n(in known heart disease group)", "Levels rise in pregnancy; interpret cautiously"],
    ["Holter Monitor", "Safe; for palpitations and arrhythmia documentation", "Ectopics very common; not necessarily abnormal"],
    ["MRI (non-contrast)", "Considered safe; no gadolinium\nUseful for aortic/complex CHD assessment", "Avoid gadolinium contrast (teratogenic concern)"],
    ["Cardiac CT", "High radiation dose; avoid if possible\nCan be used for coronary artery disease if critical", "Use only when other modalities inadequate"],
    ["Exercise Stress Test", "Safe up to moderate intensity\nUseful pre-pregnancy risk stratification", "Abnormal chronotropic response predicts complications"],
]

inv_col_widths = [3.4*cm, 8.0*cm, 5.3*cm]
inv_table = Table(inv_data, colWidths=inv_col_widths, repeatRows=1)
inv_table.setStyle(TableStyle([
    ("BACKGROUND",    (0, 0), (-1, 0), DEEP_BLUE),
    ("TEXTCOLOR",     (0, 0), (-1, 0), white),
    ("FONTNAME",      (0, 0), (-1, 0), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 0), (-1, 0), 9),
    ("ROWBACKGROUNDS", (0, 1), (-1, -1), [white, TABLE_ALT]),
    ("FONTNAME",      (0, 1), (0, -1), "Helvetica-Bold"),
    ("FONTSIZE",      (0, 1), (-1, -1), 8),
    ("TEXTCOLOR",     (0, 1), (0, -1), DEEP_BLUE),
    ("TEXTCOLOR",     (1, 1), (-1, -1), BODY_GREY),
    ("VALIGN",        (0, 0), (-1, -1), "TOP"),
    ("GRID",          (0, 0), (-1, -1), 0.4, BORDER_GREY),
    ("TOPPADDING",    (0, 0), (-1, -1), 6),
    ("BOTTOMPADDING", (0, 0), (-1, -1), 6),
    ("LEFTPADDING",   (0, 0), (-1, -1), 7),
    ("RIGHTPADDING",  (0, 0), (-1, -1), 7),
]))
story.append(inv_table)
story.append(Spacer(1, 0.4*cm))

# ══════════════════════════════════════════════════════════════════════
# 11. QUICK-REFERENCE SUMMARY
# ══════════════════════════════════════════════════════════════════════
story.append(section_header("11.  Quick-Reference Summary Card"))
story.append(Spacer(1, 0.2*cm))

summary_items = [
    ["Key Numbers to Know", [
        "Cardiac output: ↑ 30-50% (peaks 25-32 wks); ↑ further 60-80% during labour",
        "Heart rate: ↑ 10-20 bpm above baseline (peaks ~20 wks)",
        "Stroke volume: ↑ 20-50%",
        "SVR: ↓ 20-50% (key trigger for all other changes)",
        "Plasma volume: ↑ 40-50% (~2 L)",
        "Normal Hb in pregnancy: ≥ 11 g/dL (physiological anaemia)",
        "Uterine blood flow at term: 700-900 mL/min",
        "CO drop supine at term: up to 25-30%",
    ]],
    ["Cardinal Physiological Principle", [
        "SVR falls first (vasodilation from progesterone/placenta) → BP drops → sympathetic activation "
        "→ HR and SV rise → CO rises 30-50%. Plasma volume expands to fill the enlarged vascular bed.",
    ]],
    ["Highest Risk Conditions", [
        "Eisenmenger's syndrome / pulmonary hypertension (mortality 25-50%)",
        "Mitral stenosis (class III/IV)",
        "Peripartum cardiomyopathy",
        "Severe aortic stenosis",
        "Fontan circulation",
    ]],
]

for item in summary_items:
    title, bullets = item
    story.append(callout_box(title, bullets, bg=LIGHT_BLUE, border=MID_BLUE))
    story.append(Spacer(1, 0.2*cm))

story.append(Spacer(1, 0.3*cm))
story.append(HRFlowable(width="100%", thickness=1, color=BORDER_GREY))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
    "This document is a clinical summary for educational purposes. Always refer to current national and "
    "institutional guidelines for clinical decision-making. Sources: Braunwald's Heart Disease (2022), "
    "Fuster &amp; Hurst's The Heart 15th Ed, Barash Clinical Anesthesia 9th Ed, "
    "Campbell Walsh Wein Urology, Murray &amp; Nadel's Respiratory Medicine.",
    small_style
))

# ─── Build ────────────────────────────────────────────────────────────────────
doc.build(story, canvasmaker=HeaderFooterCanvas)
print(f"PDF saved to: {OUTPUT}")
Running Command

cd /home/daytona/workspace/cv-pregnancy && python generate_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/cv-pregnancy/CV_Changes_in_Pregnancy.pdf

Your clinical summary PDF is ready:

CV Changes in Pregnancy

PDF Document · PDF


Here is what the document contains across 11 sections:
SectionContent
1. OverviewIntroduction to when changes begin and why they matter
2. Key Haemodynamic ChangesFull colour-coded table - HR, CO, SV, SVR, BP, plasma volume, renal flow, etc. with magnitudes and timings
3. MechanismsWhy each change happens - progesterone, placenta, RAAS, Frank-Starling, sympathetics, relaxin
4. Trimester-by-TrimesterTimeline from 6 weeks through labour to 6 months postpartum
5. Cardiac Exam FindingsNormal vs. abnormal - symptoms, pulse, murmurs, ECG, echo
6. Systemic ChangesHaematology, renal, respiratory, coagulation, metabolic
7. High-Risk Cardiac ConditionsMitral stenosis, pulmonary HTN, peripartum CMP, Fontan, prosthetic valves
8. Supine Hypotensive SyndromeAortocaval compression mechanism + management box
9. Red Flag SymptomsColour-coded callout boxes: normal vs. refer urgently
10. InvestigationsECG, echo, BNP, MRI, CT - safety and interpretation in pregnancy
11. Quick-Reference CardKey numbers, cardinal principle, highest-risk conditions
Sources: Braunwald's Heart Disease, Fuster & Hurst's The Heart 15th Ed, Barash Clinical Anesthesia 9th Ed, Campbell Walsh Wein Urology, Murray & Nadel's Respiratory Medicine.
This is a shared conversation. Sign in to Orris to start your own chat.