Explain me 10 common heart disease with Ecg and ecg inages of those diseases

Reading File
Finding Sources
Searching Images

ECG electrocardiogram myocardial infarction STEMI

Finding Sources
Searching Images

atrial fibrillation ECG ventricular fibrillation arrhythmia

Searching Images

heart block complete AV block third degree ECG

Searching Images

ventricular tachycardia ECG wide QRS

Searching Images

left bundle branch block LBBB ECG

Searching Images

Wolff-Parkinson-White syndrome delta wave ECG pre-excitation

Searching Images

hypertrophic cardiomyopathy ECG left ventricular hypertrophy

Searching Images

long QT syndrome ECG torsades de pointes

Searching Images

pericarditis ECG saddle shaped ST elevation

Searching Images

right bundle branch block RBBB ECG RSR pattern

Here is a comprehensive guide to 10 Common Heart Diseases with ECG Findings and Images:

10 Common Heart Diseases β€” ECG Guide


1. πŸ«€ ST-Elevation Myocardial Infarction (STEMI)

What is it?

STEMI is a complete occlusion of a coronary artery causing full-thickness (transmural) myocardial necrosis. It is a cardiac emergency requiring immediate reperfusion (PCI or thrombolysis).

ECG Features

  • ST-segment elevation β‰₯1 mm in β‰₯2 contiguous leads
  • Tombstone morphology β€” convex (dome-shaped) ST elevation
  • Reciprocal ST depression in mirror-image leads
  • Pathological Q waves develop within hours (indicating necrosis)
  • T-wave inversion in later stages
TerritoryLeads with ST ElevationCulprit Artery
AnteriorV1–V4LAD
InferiorII, III, aVFRCA or LCx
LateralI, aVL, V5–V6LCx or LAD
PosteriorST depression V1–V3RCA or LCx

Anterior STEMI ECG:

Anterior STEMI β€” tombstoning ST elevation in V2–V5 with evolving Q waves (LAD occlusion)

Inferior STEMI ECG:

Inferior STEMI β€” ST elevation in II, III, aVF with reciprocal depression in I and aVL

2. πŸ’“ Atrial Fibrillation (AF)

What is it?

AF is the most common sustained cardiac arrhythmia, caused by chaotic electrical activity in the atria. It increases stroke risk 5-fold due to thrombus formation in the left atrial appendage.

ECG Features

  • Absent P waves β€” replaced by chaotic fibrillatory (f) waves
  • Irregularly irregular R-R intervals (pathognomonic)
  • Narrow QRS (unless aberrant conduction or WPW)
  • Ventricular rate typically 100–160 bpm if uncontrolled (rapid ventricular response)
  • f-waves most visible in V1 and lead II

AF ECG:

Atrial fibrillation β€” absent P waves, irregular R-R intervals, fine fibrillatory baseline

AF with Rapid Ventricular Response:

AF with RVR β€” irregularly irregular rhythm, no organized P waves, rapid narrow QRS complexes

3. 🚫 Complete (Third-Degree) AV Block

What is it?

Complete AV block is a life-threatening condition where no atrial impulses conduct to the ventricles. The atria and ventricles beat independently. Requires urgent pacemaker implantation.

ECG Features

  • AV dissociation β€” P waves and QRS complexes have no relationship
  • P-P intervals regular; R-R intervals regular β€” but independent of each other
  • Escape rhythm maintains ventricular activity:
    • Junctional escape: narrow QRS (~40–60 bpm)
    • Ventricular escape: wide QRS (~20–40 bpm)
  • P waves "march through" QRS complexes

3rd Degree Heart Block ECG:

Complete AV block β€” P waves and wide QRS complexes dissociated, ventricular escape rhythm ~36 bpm

Rhythm Strip (Lead II) β€” Complete Heart Block:

Lead II rhythm strip β€” complete heart block with junctional escape rhythm, P waves independent of narrow QRS

4. ⚑ Ventricular Tachycardia (VT)

What is it?

VT is a rapid rhythm (β‰₯3 beats at β‰₯100 bpm) originating from the ventricles. Monomorphic VT has a regular, uniform QRS; polymorphic VT has varying QRS morphology. Sustained VT can cause hemodynamic collapse.

ECG Features

  • Wide QRS complexes (>120 ms) β€” often β‰₯160 ms
  • Rapid rate β€” typically 140–250 bpm
  • AV dissociation (P waves at slower, independent rate)
  • Fusion beats and capture beats (pathognomonic when present)
  • Concordance across precordial leads (all positive or all negative)
  • Monomorphic: uniform QRS; Polymorphic: varying QRS

Monomorphic VT ECG:

Monomorphic VT β€” wide complex tachycardia, positive concordance in precordial leads, no visible P waves

5. ➑️ Left Bundle Branch Block (LBBB)

What is it?

LBBB occurs when conduction down the left bundle is blocked, forcing the left ventricle to depolarize slowly via the right bundle. New LBBB in the context of chest pain is treated as STEMI-equivalent.

ECG Features

  • Broad QRS β‰₯120 ms
  • Dominant R wave in lateral leads (I, aVL, V5–V6) β€” often notched/M-shaped
  • Deep S wave or QS in V1–V3
  • Discordant ST-T changes β€” ST/T wave opposite to main QRS deflection
  • No septal Q waves in I, aVL, V5–V6
  • Use Sgarbossa criteria to detect MI in LBBB

LBBB ECG:

LBBB β€” wide QRS, broad monophasic R waves in lateral leads, deep S-waves in V1–V3, discordant T-waves

6. ➑️ Right Bundle Branch Block (RBBB)

What is it?

RBBB results from conduction delay in the right bundle branch. The right ventricle depolarizes late via slow cell-to-cell conduction. Can be normal variant or indicate structural disease (e.g., ASD, PE, RV pressure overload).

ECG Features

  • Broad QRS β‰₯120 ms
  • RSR' (rabbit-ear) pattern in V1–V3 β€” the hallmark
  • Wide, slurred S waves in lateral leads (I, aVL, V5–V6)
  • Secondary T-wave inversion in V1–V3 (discordant)
  • Right axis deviation may be present

RBBB ECG:

RBBB β€” rSR' (rabbit-ear) pattern in V1-V3, broad slurred S waves in I, aVL, V5-V6, T-wave inversion in right precordial leads

7. πŸ”” Hypertrophic Cardiomyopathy (HCM)

What is it?

HCM is a genetic disorder (usually sarcomere protein mutations) causing asymmetric myocardial hypertrophy, typically of the interventricular septum. It is the leading cause of sudden cardiac death in young athletes.

ECG Features

  • Left ventricular hypertrophy (LVH) voltage criteria (Sokolow-Lyon: S in V1 + R in V5/V6 β‰₯35 mm)
  • Deep, widespread T-wave inversions (especially in apical HCM β€” "giant T-wave inversions" in V3–V6)
  • ST-segment depression in lateral leads
  • Strain pattern β€” ST depression + T inversion in V4–V6
  • Absence of septal Q waves in lateral leads
  • Left axis deviation

HCM ECG (Septal variant):

HCM ECG β€” high-voltage R waves, ST depression, deep T-wave inversions in precordial leads, strain pattern

Apical HCM ECG (Yamaguchi Syndrome):

Apical HCM β€” giant T-wave inversions V2–V6, high QRS voltage, classic Yamaguchi syndrome pattern

8. ⏱️ Long QT Syndrome (LQTS)

What is it?

LQTS is a disorder of cardiac repolarization (inherited or acquired) resulting in QT prolongation. This predisposes to torsades de pointes (TdP) β€” a polymorphic VT that can degenerate into ventricular fibrillation and sudden death.

ECG Features

  • Prolonged QTc (corrected QT interval):
    • Males: QTc >440 ms
    • Females: QTc >460 ms
    • Risk of TdP: QTc >500 ms
  • T-wave abnormalities: broad T waves (LQT1), notched T waves (LQT2), small T with large U wave (LQT3)
  • Torsades de Pointes: polymorphic VT with characteristic "twisting" of QRS axis around isoelectric line
  • Triggered by "short-long-short" sequence

Long QT with Torsades de Pointes ECG:

Long QT syndrome β€” QTc 680 ms, U waves in V1, progressing to polymorphic VT (torsades de pointes)

Torsades de Pointes Initiation:

Torsades de pointes β€” short-long-short trigger, polymorphic VT with twisting QRS morphology around isoelectric line

9. πŸ”΅ Acute Pericarditis

What is it?

Pericarditis is inflammation of the pericardium, commonly viral (Coxsackie B, echovirus). Presents with sharp, pleuritic chest pain relieved by leaning forward. The ECG reflects diffuse pericardial inflammation.

ECG Features (4 stages)

  • Stage 1 (hours–days): Diffuse concave ("saddle-shaped") ST elevation in nearly all leads (except aVR and V1); PR segment depression (most specific finding); PR elevation in aVR
  • Stage 2 (days): ST elevation resolves; T waves flatten
  • Stage 3 (1–3 weeks): T-wave inversions appear
  • Stage 4: ECG normalizes
  • Key differentiator from STEMI: diffuse distribution, concave shape, no Q waves, PR depression

Pericarditis ECG:

Acute pericarditis β€” diffuse saddle-shaped ST elevation, PR depression in multiple leads, reciprocal changes in aVR

10. ⚑ Wolff-Parkinson-White (WPW) Syndrome

What is it?

WPW is a pre-excitation syndrome caused by an accessory conduction pathway (Bundle of Kent) that bypasses the AV node, allowing premature ventricular activation. Patients are prone to supraventricular tachycardia and, if AF develops, can have dangerously rapid ventricular rates β†’ VF.

ECG Features

  • Short PR interval (<120 ms) β€” AV node is bypassed
  • Delta wave β€” slurred upstroke at the start of QRS (early ventricular activation)
  • Broad QRS (>120 ms) β€” combination of delta wave + normal conduction
  • Secondary ST-T changes β€” discordant to QRS
  • Accessory pathway location can be estimated from delta wave polarity
  • During orthodromic AVRT: narrow-complex tachycardia
  • During AF: wide, irregular, rapid rhythm β€” life-threatening

WPW ECG:

WPW syndrome β€” short PR interval, delta waves with slurred QRS onset, widened QRS, secondary ST-T changes

Quick Reference Summary Table

#DiseaseKey ECG Finding
1STEMIConvex ST elevation + Q waves in territory
2Atrial FibrillationNo P waves, irregularly irregular
3Complete AV BlockAV dissociation, escape rhythm
4Ventricular TachycardiaWide QRS tachycardia, AV dissociation
5LBBBBroad QRS, dominant R in lateral leads
6RBBBRSR' in V1, slurred S in lateral leads
7HCMLVH voltage + deep T inversions
8Long QT SyndromeQTc >500 ms β†’ Torsades de Pointes
9Acute PericarditisDiffuse concave ST elevation + PR depression
10WPW SyndromeShort PR + delta wave + wide QRS

Clinical Pearl: Always assess the ECG systematically β€” rate, rhythm, axis, intervals (PR, QRS, QTc), then ST-T changes. Pattern recognition is built on understanding the underlying electrophysiology of each condition.

How i get pdf of this

Reading File
Running Command

ls /home/daytona/workspace/ 2>/dev/null || echo "workspace is empty or doesn't e…

Running Command

mkdir -p /home/daytona/workspace/ecg-guide && echo "done"

Writing File

~/ecg-guide/generate_ecg_pdf.py

#!/usr/bin/env python3
"""
Generate a professional PDF for: 10 Common Heart Diseases with ECG Findings
Uses reportlab for layout and urllib to download ECG images.
"""

import urllib.request
import os
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    Image, HRFlowable, PageBreak, KeepTogether
)
from reportlab.platypus.flowables import BalancedColumns
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from io import BytesIO

OUTPUT = "/home/daytona/workspace/ecg-guide/10_Heart_Diseases_ECG_Guide.pdf"
IMG_DIR = "/home/daytona/workspace/ecg-guide/images"
os.makedirs(IMG_DIR, exist_ok=True)

# ── ECG image URLs ──────────────────────────────────────────────────────────
IMAGES = {
    "stemi_anterior": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_646aa0cfb0d976b56d82780dedb4cd025e7f67b7aa7d1163a2f05a58a08c514e.jpg",
    "stemi_inferior": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_4ff7e7260a139d9714f42c31b67dc93d733282c66f59a068801ebd1d27bf5755.jpg",
    "af_1":           "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_f3fac4aa2cfb9c0974c55a298765a969fb7578a83f9893789ff6a6e684381fd4.jpg",
    "af_2":           "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_f421022f16424f2300a3805fed62a8eb70dcacd4e53d5924eef892432da41c11.jpg",
    "av_block_1":     "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_8406f3f9d6a209bfd199f5a59f790f58cd2a726f5674a8e7fbed222b0a72b837.jpg",
    "av_block_2":     "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_e815dc24a460bb845ac47baf936d46861eadc98131a930e5ce2dea5437cf2f45.jpg",
    "vt_1":           "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_d15a92de4e89b46f273b22d254d1e30fcd6a190c6d581b193e6dd338338c6bb6.jpg",
    "lbbb_1":         "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_ea8a2b2d91edc6e5739b3da41761971059234d08e77f2192005d3e07503597d5.jpg",
    "rbbb_1":         "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_74308f325014c3be7af24c0cbb0aa2a6fe675afae1d1b0e5949c8797ae0beefa.jpg",
    "hcm_1":          "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_2910b31808487d7cd1b8678e2a6942b2ca7518030d03f48787ac4b092bd7e92e.jpg",
    "hcm_apical":     "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_f9136e8a77fe104cfbe3b8d6deb3a988a0925e95c5f6acba5afb957453257c47.jpg",
    "lqt_1":          "https://cdn.orris.care/cdss_images/HARRISON_1763034143291_d1a2f9c1-7f66-4dec-a3f8-19b81f2ba927.png",
    "lqt_tdp":        "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_63220b51cce1f40d71e2eb97047a3e0d58ad25d9d9a9b1777a668ed3417326a2.jpg",
    "pericarditis":   "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_cd4008531c1b1a2a99ab6d9b4282dcdcedfcf77c302b6ecbb7f7e01c5c985cf9.jpg",
    "wpw_1":          "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_53c53d9ed7100de15d6d512e52e2a269252a79c85c12a60e54a4ce2fc4d574ec.jpg",
}

def download_image(key, url):
    path = os.path.join(IMG_DIR, f"{key}.jpg")
    if not os.path.exists(path):
        try:
            req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
            with urllib.request.urlopen(req, timeout=15) as r:
                data = r.read()
            with open(path, "wb") as f:
                f.write(data)
            print(f"  βœ“ {key}")
        except Exception as e:
            print(f"  βœ— {key}: {e}")
            return None
    return path

def get_img(key, width=14*cm, height=None):
    path = os.path.join(IMG_DIR, f"{key}.jpg")
    if not os.path.exists(path):
        return None
    try:
        img = Image(path)
        aspect = img.imageHeight / float(img.imageWidth)
        img.drawWidth = width
        img.drawHeight = height if height else width * aspect
        # cap height
        if img.drawHeight > 7*cm:
            img.drawHeight = 7*cm
            img.drawWidth = img.drawHeight / aspect
        return img
    except:
        return None

# ── Download all images ─────────────────────────────────────────────────────
print("Downloading ECG images...")
for k, u in IMAGES.items():
    download_image(k, u)

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

BRAND_BLUE  = colors.HexColor("#1a3a5c")
ACCENT_BLUE = colors.HexColor("#2563eb")
LIGHT_BLUE  = colors.HexColor("#e8f0fe")
ACCENT_RED  = colors.HexColor("#dc2626")
LIGHT_GRAY  = colors.HexColor("#f8fafc")
MID_GRAY    = colors.HexColor("#64748b")
GREEN       = colors.HexColor("#16a34a")
ORANGE      = colors.HexColor("#ea580c")

title_style = ParagraphStyle("Title",
    fontSize=26, fontName="Helvetica-Bold", textColor=BRAND_BLUE,
    alignment=TA_CENTER, spaceAfter=4)

subtitle_style = ParagraphStyle("Subtitle",
    fontSize=13, fontName="Helvetica", textColor=MID_GRAY,
    alignment=TA_CENTER, spaceAfter=2)

disease_title_style = ParagraphStyle("DiseaseTitle",
    fontSize=16, fontName="Helvetica-Bold", textColor=BRAND_BLUE,
    spaceBefore=8, spaceAfter=4)

section_style = ParagraphStyle("Section",
    fontSize=11, fontName="Helvetica-Bold", textColor=ACCENT_BLUE,
    spaceBefore=6, spaceAfter=3)

body_style = ParagraphStyle("Body",
    fontSize=10, fontName="Helvetica", textColor=colors.HexColor("#1e293b"),
    leading=15, spaceAfter=3, alignment=TA_JUSTIFY)

bullet_style = ParagraphStyle("Bullet",
    fontSize=10, fontName="Helvetica", textColor=colors.HexColor("#1e293b"),
    leading=14, spaceAfter=2, leftIndent=14, bulletIndent=4)

caption_style = ParagraphStyle("Caption",
    fontSize=8.5, fontName="Helvetica-Oblique", textColor=MID_GRAY,
    alignment=TA_CENTER, spaceAfter=4)

toc_style = ParagraphStyle("TOC",
    fontSize=11, fontName="Helvetica", textColor=BRAND_BLUE,
    leading=18, spaceAfter=2)

def disease_number_badge(n):
    """Return a small colored badge table."""
    data = [[Paragraph(f"<b>{n}</b>", ParagraphStyle("N", fontSize=13,
             fontName="Helvetica-Bold", textColor=colors.white, alignment=TA_CENTER))]]
    t = Table(data, colWidths=[0.7*cm], rowHeights=[0.7*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), ACCENT_BLUE),
        ("ROUNDEDCORNERS", [4]),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("ALIGN", (0,0), (-1,-1), "CENTER"),
    ]))
    return t

def section_header_table(number, title, subtitle=""):
    """Styled header row for each disease section."""
    badge = disease_number_badge(number)
    h = Paragraph(f"<b>{title}</b>", ParagraphStyle("H", fontSize=16,
        fontName="Helvetica-Bold", textColor=BRAND_BLUE, leading=19))
    sub = Paragraph(subtitle, ParagraphStyle("Sub", fontSize=10,
        fontName="Helvetica-Oblique", textColor=MID_GRAY))
    inner = Table([[h], [sub]], colWidths=[13*cm])
    inner.setStyle(TableStyle([("LEFTPADDING",(0,0),(-1,-1),0),
                                ("BOTTOMPADDING",(0,0),(-1,-1),0),
                                ("TOPPADDING",(0,0),(-1,-1),0)]))
    t = Table([[badge, inner]], colWidths=[1.1*cm, 13*cm])
    t.setStyle(TableStyle([
        ("VALIGN",(0,0),(-1,-1),"MIDDLE"),
        ("LEFTPADDING",(0,0),(-1,-1),4),
        ("BACKGROUND",(0,0),(-1,-1),LIGHT_BLUE),
        ("BOX",(0,0),(-1,-1),1,colors.HexColor("#bfdbfe")),
        ("TOPPADDING",(0,0),(-1,-1),6),
        ("BOTTOMPADDING",(0,0),(-1,-1),6),
    ]))
    return t

def ecg_box(key, caption, width=14*cm):
    img = get_img(key, width=width)
    items = []
    if img:
        items.append(img)
    items.append(Paragraph(f"<i>{caption}</i>", caption_style))
    box = Table([[items[0] if img else Paragraph("[Image unavailable]", caption_style)],
                 [items[-1]]], colWidths=[width])
    box.setStyle(TableStyle([
        ("ALIGN",(0,0),(-1,-1),"CENTER"),
        ("BACKGROUND",(0,0),(0,0),colors.HexColor("#f1f5f9")),
        ("BOX",(0,0),(-1,-1),0.5,colors.HexColor("#cbd5e1")),
        ("TOPPADDING",(0,0),(-1,-1),4),
        ("BOTTOMPADDING",(0,0),(-1,-1),4),
    ]))
    return box

def two_ecg_row(key1, cap1, key2, cap2):
    """Side-by-side ECG images."""
    w = 6.8*cm
    img1 = get_img(key1, width=w)
    img2 = get_img(key2, width=w)
    def cell(img, cap):
        items = []
        if img: items.append(img)
        else: items.append(Paragraph("[Image unavailable]", caption_style))
        items.append(Paragraph(f"<i>{cap}</i>", caption_style))
        t = Table([[items[0]],[items[1]]], colWidths=[w])
        t.setStyle(TableStyle([
            ("ALIGN",(0,0),(-1,-1),"CENTER"),
            ("BACKGROUND",(0,0),(0,0),colors.HexColor("#f1f5f9")),
            ("BOX",(0,0),(-1,-1),0.5,colors.HexColor("#cbd5e1")),
            ("TOPPADDING",(0,0),(-1,-1),3),
            ("BOTTOMPADDING",(0,0),(-1,-1),3),
        ]))
        return t
    row = Table([[cell(img1,cap1), cell(img2,cap2)]], colWidths=[w+4, w+4])
    row.setStyle(TableStyle([("ALIGN",(0,0),(-1,-1),"CENTER"),
                              ("VALIGN",(0,0),(-1,-1),"TOP"),
                              ("LEFTPADDING",(0,0),(-1,-1),2),
                              ("RIGHTPADDING",(0,0),(-1,-1),2)]))
    return row

def bullets(items):
    return [Paragraph(f"β€’ {t}", bullet_style) for t in items]

def build_pdf():
    doc = SimpleDocTemplate(OUTPUT, pagesize=A4,
        leftMargin=1.8*cm, rightMargin=1.8*cm,
        topMargin=2*cm, bottomMargin=2*cm,
        title="10 Common Heart Diseases β€” ECG Guide",
        author="Orris Medical AI")

    story = []

    # ── COVER PAGE ────────────────────────────────────────────────────────
    story.append(Spacer(1, 1.5*cm))

    # Top color bar
    bar = Table([[""]],colWidths=[17*cm], rowHeights=[0.5*cm])
    bar.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),ACCENT_BLUE)]))
    story.append(bar)
    story.append(Spacer(1, 0.6*cm))

    story.append(Paragraph("10 Common Heart Diseases", title_style))
    story.append(Paragraph("ECG Findings &amp; Diagnostic Images", ParagraphStyle(
        "Sub2", fontSize=16, fontName="Helvetica", textColor=ACCENT_BLUE,
        alignment=TA_CENTER, spaceAfter=8)))
    story.append(Spacer(1, 0.3*cm))
    story.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor("#bfdbfe")))
    story.append(Spacer(1, 0.3*cm))
    story.append(Paragraph("A comprehensive clinical reference with real ECG tracings",
        subtitle_style))
    story.append(Paragraph("Generated by Orris Medical AI Β· May 2026",
        ParagraphStyle("Date", fontSize=9, fontName="Helvetica",
            textColor=MID_GRAY, alignment=TA_CENTER)))
    story.append(Spacer(1, 0.8*cm))

    # Cover table of contents
    toc_data = [
        [Paragraph("<b>#</b>", ParagraphStyle("TH", fontSize=10, fontName="Helvetica-Bold",
                   textColor=colors.white, alignment=TA_CENTER)),
         Paragraph("<b>Disease</b>", ParagraphStyle("TH", fontSize=10, fontName="Helvetica-Bold",
                   textColor=colors.white)),
         Paragraph("<b>Key ECG Finding</b>", ParagraphStyle("TH", fontSize=10, fontName="Helvetica-Bold",
                   textColor=colors.white))],
        ["1", "ST-Elevation MI (STEMI)", "Convex ST elevation + Q waves"],
        ["2", "Atrial Fibrillation", "No P waves Β· Irregularly irregular"],
        ["3", "Complete AV Block (3Β°)", "AV dissociation Β· Escape rhythm"],
        ["4", "Ventricular Tachycardia", "Wide QRS tachycardia Β· AV dissociation"],
        ["5", "Left Bundle Branch Block", "Broad QRS Β· Dominant R in lateral leads"],
        ["6", "Right Bundle Branch Block", "RSR' in V1 Β· Slurred S in lateral leads"],
        ["7", "Hypertrophic Cardiomyopathy", "LVH voltage Β· Deep T-wave inversions"],
        ["8", "Long QT Syndrome", "QTc >500 ms β†’ Torsades de Pointes"],
        ["9", "Acute Pericarditis", "Diffuse concave ST elevation Β· PR depression"],
        ["10","Wolff-Parkinson-White (WPW)", "Short PR Β· Delta wave Β· Wide QRS"],
    ]
    row_colors = [
        ("BACKGROUND", (0, 0), (-1, 0), BRAND_BLUE),
    ]
    for i in range(1, len(toc_data)):
        bg = LIGHT_BLUE if i % 2 == 0 else colors.white
        row_colors.append(("BACKGROUND", (0, i), (-1, i), bg))

    toc_table = Table(toc_data, colWidths=[0.8*cm, 6*cm, 8.5*cm])
    toc_table.setStyle(TableStyle([
        ("FONTNAME", (0, 1), (-1, -1), "Helvetica"),
        ("FONTSIZE", (0, 1), (-1, -1), 10),
        ("TEXTCOLOR", (0, 1), (-1, -1), BRAND_BLUE),
        ("ALIGN", (0, 0), (0, -1), "CENTER"),
        ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
        ("GRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#e2e8f0")),
        ("TOPPADDING", (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
        ("LEFTPADDING", (0, 0), (-1, -1), 6),
    ] + row_colors))
    story.append(toc_table)
    story.append(Spacer(1, 0.5*cm))

    bot_bar = Table([[""]],colWidths=[17*cm], rowHeights=[0.3*cm])
    bot_bar.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),ACCENT_BLUE)]))
    story.append(bot_bar)
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════
    # DISEASE 1 β€” STEMI
    # ══════════════════════════════════════════════════════════════════
    story.append(section_header_table(1, "ST-Elevation Myocardial Infarction (STEMI)",
        "Complete coronary occlusion causing transmural myocardial necrosis"))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph("Overview", section_style))
    story.append(Paragraph(
        "STEMI results from acute, complete occlusion of a coronary artery, leading to full-thickness "
        "(transmural) ischemia and necrosis. It is a life-threatening emergency requiring immediate "
        "reperfusion β€” primary percutaneous coronary intervention (PCI) within 90 minutes is the gold "
        "standard. The ECG is the cornerstone of rapid diagnosis.", body_style))

    story.append(Paragraph("ECG Features", section_style))
    story += bullets([
        "ST-segment elevation β‰₯1 mm in β‰₯2 contiguous limb leads, or β‰₯2 mm in precordial leads",
        "Convex (tombstone) ST morphology β€” dome-shaped, high-risk marker",
        "Reciprocal ST depression in mirror-image leads",
        "Pathological Q waves develop within hours β†’ indicate myocardial necrosis",
        "Hyperacute T waves may precede ST elevation (earliest sign)",
        "T-wave inversion follows in the evolutionary phase",
    ])
    story.append(Spacer(1, 0.2*cm))

    # Territory table
    terr_data = [
        [Paragraph("<b>Territory</b>", ParagraphStyle("TH", fontSize=9.5, fontName="Helvetica-Bold", textColor=colors.white)),
         Paragraph("<b>Leads with ST Elevation</b>", ParagraphStyle("TH", fontSize=9.5, fontName="Helvetica-Bold", textColor=colors.white)),
         Paragraph("<b>Culprit Artery</b>", ParagraphStyle("TH", fontSize=9.5, fontName="Helvetica-Bold", textColor=colors.white))],
        ["Anterior", "V1 – V4", "LAD"],
        ["Inferior", "II, III, aVF", "RCA or LCx"],
        ["Lateral", "I, aVL, V5 – V6", "LCx or LAD diagonal"],
        ["Posterior", "ST depression V1–V3 (mirror)", "RCA or LCx"],
    ]
    terr_t = Table(terr_data, colWidths=[3.5*cm, 6*cm, 6*cm])
    terr_t.setStyle(TableStyle([
        ("BACKGROUND",(0,0),(-1,0), BRAND_BLUE),
        ("FONTNAME",(0,1),(-1,-1),"Helvetica"), ("FONTSIZE",(0,0),(-1,-1),9.5),
        ("GRID",(0,0),(-1,-1),0.5,colors.HexColor("#e2e8f0")),
        ("BACKGROUND",(0,2),(-1,2),LIGHT_BLUE),
        ("BACKGROUND",(0,4),(-1,4),LIGHT_BLUE),
        ("ALIGN",(0,0),(-1,-1),"CENTER"),
        ("VALIGN",(0,0),(-1,-1),"MIDDLE"),
        ("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),4),
    ]))
    story.append(terr_t)
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph("ECG Examples", section_style))
    story.append(two_ecg_row("stemi_anterior",
        "Anterior STEMI β€” Tombstone ST elevation V2–V5, evolving Q waves (LAD occlusion)",
        "stemi_inferior",
        "Inferior STEMI β€” ST elevation in II, III, aVF; reciprocal depression in I and aVL"))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════
    # DISEASE 2 β€” ATRIAL FIBRILLATION
    # ══════════════════════════════════════════════════════════════════
    story.append(section_header_table(2, "Atrial Fibrillation (AF)",
        "Most common sustained cardiac arrhythmia β€” 5Γ— increased stroke risk"))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph("Overview", section_style))
    story.append(Paragraph(
        "AF arises from chaotic, disorganised electrical activity in the atria, firing at 350–600 impulses "
        "per minute. The AV node acts as a filter, resulting in an irregular ventricular response. "
        "Loss of atrial contraction causes blood stasis in the left atrial appendage, increasing thromboembolic "
        "risk β€” making anticoagulation a central management decision.", body_style))

    story.append(Paragraph("ECG Features", section_style))
    story += bullets([
        "Complete absence of organised P waves β€” replaced by irregular fibrillatory (f) waves",
        "Irregularly irregular R-R intervals β€” the pathognomonic hallmark",
        "f-waves most visible in lead V1 and lead II",
        "Narrow QRS complexes (unless aberrant conduction or WPW is present)",
        "Ventricular rate 100–160 bpm if uncontrolled (rapid ventricular response)",
        "Coarse AF: prominent f-waves (often valvular); Fine AF: subtle f-waves",
    ])
    story.append(Spacer(1, 0.2*cm))

    story.append(Paragraph("ECG Examples", section_style))
    story.append(two_ecg_row("af_1",
        "AF β€” absent P waves, irregular R-R intervals, coarse fibrillatory baseline",
        "af_2",
        "AF with Rapid Ventricular Response β€” narrow QRS tachycardia, no organised P waves"))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════
    # DISEASE 3 β€” COMPLETE AV BLOCK
    # ══════════════════════════════════════════════════════════════════
    story.append(section_header_table(3, "Complete (Third-Degree) AV Block",
        "Total failure of AV conduction β€” requires urgent pacemaker"))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph("Overview", section_style))
    story.append(Paragraph(
        "In complete AV block, no atrial impulses reach the ventricles due to total failure of the "
        "AV conduction system. The atria and ventricles beat completely independently. A subsidiary "
        "pacemaker (junctional or ventricular) maintains cardiac output at a slow escape rate. "
        "Without treatment, patients may develop syncope or cardiac arrest. Permanent pacemaker "
        "implantation is usually required.", body_style))

    story.append(Paragraph("ECG Features", section_style))
    story += bullets([
        "Complete AV dissociation β€” P waves and QRS complexes are independent",
        "Regular P-P intervals at a faster atrial rate; regular R-R intervals at a slower escape rate",
        "P waves 'march through' QRS complexes and T waves without relationship",
        "Junctional escape: narrow QRS at 40–60 bpm (block above or at His)",
        "Ventricular escape: wide QRS at 20–40 bpm (block below His bundle) β€” more unstable",
        "Wide QRS escape suggests infra-Hisian block β€” higher risk",
    ])
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph("ECG Examples", section_style))
    story.append(two_ecg_row("av_block_1",
        "Complete AV Block β€” wide QRS ventricular escape, P waves dissociated, post-tricuspid valve surgery",
        "av_block_2",
        "Lead II rhythm strip β€” 3rd degree block with narrow junctional escape, P waves independent"))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════
    # DISEASE 4 β€” VENTRICULAR TACHYCARDIA
    # ══════════════════════════════════════════════════════════════════
    story.append(section_header_table(4, "Ventricular Tachycardia (VT)",
        "Rapid ventricular rhythm β€” can cause haemodynamic collapse"))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph("Overview", section_style))
    story.append(Paragraph(
        "VT is defined as β‰₯3 consecutive ventricular beats at a rate β‰₯100 bpm, originating below the "
        "His bundle. Monomorphic VT has uniform QRS morphology; polymorphic VT has varying morphology. "
        "Sustained VT (>30 seconds or causing haemodynamic compromise) is a medical emergency. "
        "It most often occurs in the context of structural heart disease (prior MI, cardiomyopathy).", body_style))

    story.append(Paragraph("ECG Features", section_style))
    story += bullets([
        "Wide QRS complexes (>120 ms, often β‰₯160 ms) at rapid rate (140–250 bpm)",
        "AV dissociation β€” P waves present at slower, independent rate (pathognomonic)",
        "Fusion beats and capture beats β€” highly specific for VT when present",
        "Precordial concordance β€” all leads V1–V6 same direction (all positive or all negative)",
        "Monomorphic VT: uniform QRS; Polymorphic VT: continuously varying QRS",
        "Brugada/Vereckei criteria help differentiate VT from SVT with aberrancy",
    ])
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph("ECG Example", section_style))
    story.append(ecg_box("vt_1",
        "Monomorphic VT β€” regular wide-complex tachycardia, positive concordance V1–V6, no visible P waves"))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════
    # DISEASE 5 β€” LBBB
    # ══════════════════════════════════════════════════════════════════
    story.append(section_header_table(5, "Left Bundle Branch Block (LBBB)",
        "New LBBB + chest pain = STEMI-equivalent until proven otherwise"))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph("Overview", section_style))
    story.append(Paragraph(
        "LBBB occurs when conduction through the left bundle is delayed or blocked. The left ventricle "
        "depolarises slowly via cell-to-cell spread from the right. This causes characteristic wide, "
        "abnormal QRS complexes and discordant repolarisation changes. New LBBB in the context of "
        "acute chest pain is treated as STEMI-equivalent β€” Sgarbossa criteria help identify superimposed MI.", body_style))

    story.append(Paragraph("ECG Features", section_style))
    story += bullets([
        "Broad QRS β‰₯120 ms (usually 140–160 ms in complete LBBB)",
        "Broad, monophasic R waves in lateral leads (I, aVL, V5–V6) β€” often notched 'M-shaped'",
        "Deep S wave or QS complex in right precordial leads (V1–V3)",
        "Discordant ST-T changes β€” ST/T wave opposite to main QRS deflection",
        "No septal Q waves in I, aVL, V5–V6 (septal activation reversed)",
        "Sgarbossa criteria: concordant ST elevation β‰₯1 mm, concordant ST depression β‰₯1 mm in V1–V3, "
        "or excessive discordant ST elevation >25% of S wave depth",
    ])
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph("ECG Example", section_style))
    story.append(ecg_box("lbbb_1",
        "LBBB β€” broad QRS, monophasic R waves in I/aVL/V5–V6, deep S in V1–V3, discordant T-waves"))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════
    # DISEASE 6 β€” RBBB
    # ══════════════════════════════════════════════════════════════════
    story.append(section_header_table(6, "Right Bundle Branch Block (RBBB)",
        "Delayed right ventricular depolarisation β€” RSR' pattern in V1"))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph("Overview", section_style))
    story.append(Paragraph(
        "RBBB results from conduction delay in the right bundle branch. The right ventricle depolarises "
        "late via slow cell-to-cell spread. RBBB can be a normal variant in young adults or may indicate "
        "underlying pathology: right ventricular pressure overload (PE, pulmonary hypertension), atrial "
        "septal defect, right heart ischaemia, or degenerative conduction disease.", body_style))

    story.append(Paragraph("ECG Features", section_style))
    story += bullets([
        "Broad QRS β‰₯120 ms",
        "RSR' ('rabbit-ear' or 'M-shaped') pattern in right precordial leads V1–V3 β€” hallmark feature",
        "Tall, secondary R wave (R') in V1 representing delayed RV depolarisation",
        "Wide, slurred S waves in lateral leads (I, aVL, V5–V6)",
        "Secondary T-wave inversion in V1–V3 (discordant β€” normal finding in RBBB)",
        "Axis may be rightward; right heart strain pattern may co-exist",
    ])
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph("ECG Example", section_style))
    story.append(ecg_box("rbbb_1",
        "RBBB β€” rSR' 'rabbit-ear' in V1–V3 (blue arrows), broad slurred S in I/aVL/V5–V6 (red arrows), T-inversion V1–V3"))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════
    # DISEASE 7 β€” HCM
    # ══════════════════════════════════════════════════════════════════
    story.append(section_header_table(7, "Hypertrophic Cardiomyopathy (HCM)",
        "Leading cause of sudden cardiac death in young athletes"))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph("Overview", section_style))
    story.append(Paragraph(
        "HCM is an autosomal dominant genetic disorder (most commonly Ξ²-myosin heavy chain mutations) "
        "causing disproportionate myocardial hypertrophy, typically asymmetric septal hypertrophy. "
        "The hallmarks are diastolic dysfunction, dynamic LVOT obstruction, and myofiber disarray, "
        "which creates an arrhythmogenic substrate. Most patients are asymptomatic but are at risk "
        "for exertional syncope and sudden cardiac death from VF.", body_style))

    story.append(Paragraph("ECG Features", section_style))
    story += bullets([
        "Left ventricular hypertrophy (LVH) voltage criteria β€” Sokolow-Lyon: S(V1) + R(V5/V6) β‰₯35 mm",
        "Deep, widespread T-wave inversions β€” especially giant T-wave inversions in apical variant (Yamaguchi syndrome)",
        "ST-segment depression with strain pattern in V4–V6",
        "Absence of septal Q waves in lateral leads (despite hypertrophy)",
        "Left axis deviation common; PR interval may be short",
        "Abnormal ECG present in ~95% of HCM patients β€” normal ECG makes HCM unlikely",
    ])
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph("ECG Examples", section_style))
    story.append(two_ecg_row("hcm_1",
        "HCM (Septal) β€” high-voltage R waves, ST depression, deep T-wave inversions, strain pattern",
        "hcm_apical",
        "Apical HCM (Yamaguchi) β€” giant T-wave inversions V2–V6, high QRS voltage"))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════
    # DISEASE 8 β€” LONG QT
    # ══════════════════════════════════════════════════════════════════
    story.append(section_header_table(8, "Long QT Syndrome (LQTS)",
        "Repolarisation disorder β€” QTc >500 ms risks Torsades de Pointes β†’ VF"))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph("Overview", section_style))
    story.append(Paragraph(
        "LQTS is a disorder of cardiac ion channels causing prolonged ventricular repolarisation. "
        "It may be inherited (LQT1: KCNQ1; LQT2: KCNH2; LQT3: SCN5A mutations) or acquired "
        "(drugs, electrolyte disturbances). Prolonged repolarisation creates conditions for early "
        "afterdepolarisations, triggering polymorphic VT (torsades de pointes β€” TdP), which can "
        "degenerate into ventricular fibrillation and sudden death.", body_style))

    story.append(Paragraph("ECG Features", section_style))
    story += bullets([
        "Prolonged QTc: males >440 ms, females >460 ms; risk of TdP when QTc >500 ms",
        "Use Bazett formula: QTc = QT / √(RR interval in seconds)",
        "LQT1: broad-based T waves; LQT2: notched/bifid T waves; LQT3: long isoelectric ST, then peaked T",
        "T-wave alternans: beat-to-beat T-wave amplitude variation β€” marker of high arrhythmic risk",
        "Torsades de Pointes: polymorphic VT with characteristic 'twisting' of QRS axis",
        "Triggered by 'short-long-short' R-R sequence (PVC β†’ compensatory pause β†’ next beat triggers TdP)",
    ])
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph("ECG Examples", section_style))
    story.append(two_ecg_row("lqt_1",
        "LQTS β€” QTc 680 ms, U waves (arrows in V1), progressing to polymorphic VT (torsades de pointes)",
        "lqt_tdp",
        "TdP initiation β€” short-long-short trigger, characteristic 'twisting' polymorphic VT"))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════
    # DISEASE 9 β€” PERICARDITIS
    # ══════════════════════════════════════════════════════════════════
    story.append(section_header_table(9, "Acute Pericarditis",
        "Pericardial inflammation β€” diffuse saddle-shaped ST elevation + PR depression"))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph("Overview", section_style))
    story.append(Paragraph(
        "Acute pericarditis is inflammation of the pericardium, most commonly viral in aetiology "
        "(Coxsackievirus B, echovirus, adenovirus). It presents with sharp, pleuritic chest pain "
        "that is worse supine and relieved by sitting forward (friction rub may be heard). "
        "The ECG changes reflect current-of-injury from the adjacent inflamed epicardium across "
        "the entire pericardial surface, producing characteristic diffuse changes distinct from STEMI.", body_style))

    story.append(Paragraph("ECG Features (4 Evolutionary Stages)", section_style))
    story += bullets([
        "Stage 1 (hours–days): Diffuse concave ('saddle-shaped') ST elevation in nearly all leads except aVR and V1; PR segment depression most evident in lead II β€” most specific sign; reciprocal PR elevation in aVR",
        "Stage 2 (days): ST elevation normalises; T waves flatten",
        "Stage 3 (1–3 weeks): Diffuse T-wave inversions develop",
        "Stage 4 (weeks): ECG normalises completely",
        "Key differences from STEMI: diffuse distribution (not coronary territory), concave morphology, PR depression, no Q waves",
        "Spodick's sign: downward slope of TP segment in multiple leads",
    ])
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph("ECG Example", section_style))
    story.append(ecg_box("pericarditis",
        "Acute pericarditis β€” diffuse concave/saddle-shaped ST elevation, PR depression in II/III/aVF/V2–V6, ST depression and PR elevation in aVR"))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════
    # DISEASE 10 β€” WPW
    # ══════════════════════════════════════════════════════════════════
    story.append(section_header_table(10, "Wolff-Parkinson-White (WPW) Syndrome",
        "Accessory pathway pre-excitation β€” AF in WPW can be lethal"))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph("Overview", section_style))
    story.append(Paragraph(
        "WPW syndrome results from an accessory conduction pathway (Bundle of Kent) that bypasses the "
        "AV node, allowing premature ventricular pre-excitation. The delta wave on ECG represents this "
        "early activation. Patients are prone to re-entrant tachycardias (AVRT). Critically, if AF "
        "develops, impulses can conduct rapidly over the accessory pathway without AV nodal protection "
        "β†’ ventricular rates of 200–300 bpm β†’ ventricular fibrillation β†’ sudden death. "
        "Definitive treatment is catheter ablation of the accessory pathway.", body_style))

    story.append(Paragraph("ECG Features", section_style))
    story += bullets([
        "Short PR interval (<120 ms) β€” AV node bypassed, impulse arrives early",
        "Delta wave β€” slurred, gradual upstroke at the start of the QRS complex",
        "Broad QRS (>120 ms) β€” combination of delta wave + normal His-Purkinje conduction (fusion beat)",
        "Secondary discordant ST-T changes β€” opposite to main QRS deflection",
        "Accessory pathway location estimated from delta wave polarity across leads",
        "During orthodromic AVRT: narrow-complex regular tachycardia (most common)",
        "During AF with WPW: wide, irregular, very rapid tachycardia β€” life-threatening; AVOID adenosine/verapamil/digoxin",
    ])
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph("ECG Example", section_style))
    story.append(ecg_box("wpw_1",
        "WPW syndrome β€” short PR interval, delta waves (arrows on II/III), widened QRS, secondary ST-T changes; anteroseptal accessory pathway"))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════
    # SUMMARY TABLE
    # ══════════════════════════════════════════════════════════════════
    story.append(Paragraph("Quick Reference Summary", ParagraphStyle("QR",
        fontSize=18, fontName="Helvetica-Bold", textColor=BRAND_BLUE,
        alignment=TA_CENTER, spaceAfter=8)))
    story.append(HRFlowable(width="100%", thickness=1, color=ACCENT_BLUE))
    story.append(Spacer(1, 0.3*cm))

    def ph(t, bold=False, color=colors.white, size=9.5):
        fn = "Helvetica-Bold" if bold else "Helvetica"
        return Paragraph(f"<b>{t}</b>" if bold else t, ParagraphStyle("PH", fontSize=size,
            fontName=fn, textColor=color, alignment=TA_CENTER, leading=13))

    summary_data = [
        [ph("#", bold=True), ph("Disease", bold=True), ph("Key ECG Finding", bold=True),
         ph("Emergency?", bold=True)],
        ["1", "STEMI", "Convex ST elevation + Q waves in territory", "YES β€” Immediate PCI"],
        ["2", "Atrial Fibrillation", "No P waves Β· Irregularly irregular", "If rapid / unstable"],
        ["3", "Complete AV Block", "AV dissociation Β· Escape rhythm", "YES β€” Pacemaker"],
        ["4", "Ventricular Tachycardia", "Wide QRS tachycardia Β· AV dissociation", "YES β€” Cardioversion"],
        ["5", "LBBB", "Broad QRS Β· Dominant R in lateral leads", "If new + chest pain"],
        ["6", "RBBB", "RSR' in V1 Β· Slurred S in lateral leads", "Investigate cause"],
        ["7", "HCM", "LVH voltage + deep T-wave inversions", "Risk stratify for SCD"],
        ["8", "Long QT Syndrome", "QTc >500 ms β†’ Torsades de Pointes", "If TdP / syncope"],
        ["9", "Acute Pericarditis", "Diffuse concave ST + PR depression", "Usually no"],
        ["10","WPW Syndrome", "Short PR + Delta wave + Wide QRS", "YES if AF with WPW"],
    ]
    
    s_row_colors = [("BACKGROUND", (0,0), (-1,0), BRAND_BLUE)]
    for i in range(1, len(summary_data)):
        bg = LIGHT_BLUE if i % 2 == 0 else colors.white
        s_row_colors.append(("BACKGROUND",(0,i),(-1,i),bg))
    # highlight emergency rows
    for i, row in enumerate(summary_data[1:], 1):
        if "YES" in str(row[-1]):
            s_row_colors.append(("TEXTCOLOR",(3,i),(3,i), ACCENT_RED))
            s_row_colors.append(("FONTNAME",(3,i),(3,i),"Helvetica-Bold"))

    s_table = Table(summary_data, colWidths=[0.7*cm, 4.5*cm, 7*cm, 4.5*cm])
    s_table.setStyle(TableStyle([
        ("FONTNAME",(0,1),(-1,-1),"Helvetica"),
        ("FONTSIZE",(0,0),(-1,-1),9),
        ("TEXTCOLOR",(0,1),(-1,-1),BRAND_BLUE),
        ("ALIGN",(0,0),(-1,-1),"CENTER"),
        ("VALIGN",(0,0),(-1,-1),"MIDDLE"),
        ("GRID",(0,0),(-1,-1),0.5,colors.HexColor("#e2e8f0")),
        ("TOPPADDING",(0,0),(-1,-1),5),
        ("BOTTOMPADDING",(0,0),(-1,-1),5),
        ("LEFTPADDING",(0,0),(-1,-1),5),
    ] + s_row_colors))
    story.append(s_table)
    story.append(Spacer(1, 0.5*cm))

    # Clinical pearl box
    pearl_inner = Paragraph(
        "<b>Clinical Pearl:</b> Always assess the ECG systematically β€” "
        "<b>Rate β†’ Rhythm β†’ Axis β†’ Intervals (PR, QRS, QTc) β†’ ST-T changes</b>. "
        "Pattern recognition is built on understanding the underlying electrophysiology of each condition. "
        "A normal ECG does not exclude significant heart disease.",
        ParagraphStyle("Pearl", fontSize=10, fontName="Helvetica",
            textColor=BRAND_BLUE, leading=15, alignment=TA_JUSTIFY))
    pearl_box = Table([[pearl_inner]], colWidths=[16.4*cm])
    pearl_box.setStyle(TableStyle([
        ("BACKGROUND",(0,0),(-1,-1), colors.HexColor("#fffbeb")),
        ("BOX",(0,0),(-1,-1),1.5, colors.HexColor("#f59e0b")),
        ("TOPPADDING",(0,0),(-1,-1),10),
        ("BOTTOMPADDING",(0,0),(-1,-1),10),
        ("LEFTPADDING",(0,0),(-1,-1),12),
        ("RIGHTPADDING",(0,0),(-1,-1),12),
    ]))
    story.append(pearl_box)
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph(
        "ECG images sourced from PMC Open Access Clinical VQA dataset and Harrison's Principles of Internal Medicine, 21st Ed. "
        "Generated by Orris Medical AI Β· May 2026 Β· For educational purposes only.",
        ParagraphStyle("Footer", fontSize=7.5, fontName="Helvetica-Oblique",
            textColor=MID_GRAY, alignment=TA_CENTER)))

    # ── Build ──────────────────────────────────────────────────────
    print("\nBuilding PDF...")
    doc.build(story)
    print(f"βœ“ PDF saved to: {OUTPUT}")

build_pdf()
You've run out of free credits. Sign up for a free account to continue using Orris.
This is a shared conversation. Sign in to Orris to start your own chat.