Infective endocarditis clinical symptoms causes and treatment and basic to clinical

Reading File
Finding Sources
Searching Images

infective endocarditis vegetation heart valve clinical findings

This clinical photograph displays a gross anatomical autopsy section of a human heart, focusing on the mitral valve apparatus. The image serves as a pathological specimen demonstrating infective endocarditis. Key findings include the presence of friable, irregular, brownish-red masses, identified as vegetations (indicated by arrows), attached to the mitral valve leaflets. The leaflets themselves show significant structural disruption, ulceration, and non-uniform thickening. Surrounding tissues exhibit signs of acute pathology, including hemorrhagic areas (deep red), inflammatory changes, and yellowish epicardial or valvular fat deposits. The underlying myocardium appears congested. This visual illustrates the hallmark gross features of valvular destruction and vegetation formation in bacterial endocarditis, highlighting the clinical relevance of the condition in causing valvular insufficiency and potential embolic events. The content is suitable for advanced medical education in pathology and cardiology, specifically regarding the morphological manifestations of endocardial infections.

This clinical photograph displays a gross anatomical autopsy section of a human heart, focusing on the mitral valve apparatus. The image serves as a pathological specimen demonstrating infective endocarditis. Key findings include the presence of friable, irregular, brownish-red masses, identified as vegetations (indicated by arrows), attached to the mitral valve leaflets. The leaflets themselves show significant structural disruption, ulceration, and non-uniform thickening. Surrounding tissues exhibit signs of acute pathology, including hemorrhagic areas (deep red), inflammatory changes, and yellowish epicardial or valvular fat deposits. The underlying myocardium appears congested. This visual illustrates the hallmark gross features of valvular destruction and vegetation formation in bacterial endocarditis, highlighting the clinical relevance of the condition in causing valvular insufficiency and potential embolic events. The content is suitable for advanced medical education in pathology and cardiology, specifically regarding the morphological manifestations of endocardial infections.

Diagnostic Image: This clinical echocardiogram shows a transthoracic parasternal long-axis view of the heart. Two red arrows and a text label point to 'VEGETATION' located on the aortic valve leaflets. The vegetations appear as small, irregular, and heterogeneous masses with mixed echogenicity (containing both hyperechoic and hypoechoic elements) attached to the valvular structure. These findings are characteristic of infective endocarditis, illustrating the presence of friable microbial growths on the heart valves. The imaging highlights the typical morphology and location of valvular vegetations, which can lead to complications such as aortic regurgitation. This visual is intended for medical education regarding cardiology, infectious diseases, and diagnostic ultrasound interpretation.

Diagnostic Image: This clinical echocardiogram shows a transthoracic parasternal long-axis view of the heart. Two red arrows and a text label point to 'VEGETATION' located on the aortic valve leaflets. The vegetations appear as small, irregular, and heterogeneous masses with mixed echogenicity (containing both hyperechoic and hypoechoic elements) attached to the valvular structure. These findings are characteristic of infective endocarditis, illustrating the presence of friable microbial growths on the heart valves. The imaging highlights the typical morphology and location of valvular vegetations, which can lead to complications such as aortic regurgitation. This visual is intended for medical education regarding cardiology, infectious diseases, and diagnostic ultrasound interpretation.

Two-panel diagnostic echocardiography (ultrasound) images demonstrating infective endocarditis with multiple vegetations on the left heart valves. The left panel shows a parasternal long-axis view of the bicuspid aortic valve, with hyperechoic, irregular masses (vegetations) attached to the tips of the anterior (yellow arrow) and posterior (blue arrow) leaflets. The right panel highlights the mitral valve apparatus, where another distinct hyperechoic vegetation is visible on the body of the anterior mitral valve leaflet (green arrow). These findings are highly suggestive of active infective endocarditis, illustrating the characteristic appearance of mobile, irregular echoes attached to valvular endocardial surfaces. Clinical relevance includes the high risk of systemic embolization given the size and location of these vegetations, commonly associated with pathogens such as Streptococcus gordonii. This visual serves as an educational tool for identifying valvular pathology, measuring vegetation dimensions, and assessing the risk of secondary complications like septic emboli in a cardiothoracic or infectious disease context.

Two-panel diagnostic echocardiography (ultrasound) images demonstrating infective endocarditis with multiple vegetations on the left heart valves. The left panel shows a parasternal long-axis view of the bicuspid aortic valve, with hyperechoic, irregular masses (vegetations) attached to the tips of the anterior (yellow arrow) and posterior (blue arrow) leaflets. The right panel highlights the mitral valve apparatus, where another distinct hyperechoic vegetation is visible on the body of the anterior mitral valve leaflet (green arrow). These findings are highly suggestive of active infective endocarditis, illustrating the characteristic appearance of mobile, irregular echoes attached to valvular endocardial surfaces. Clinical relevance includes the high risk of systemic embolization given the size and location of these vegetations, commonly associated with pathogens such as Streptococcus gordonii. This visual serves as an educational tool for identifying valvular pathology, measuring vegetation dimensions, and assessing the risk of secondary complications like septic emboli in a cardiothoracic or infectious disease context.

Two-panel intraoperative clinical photograph (A and B) showing findings during emergency cardiac surgery for infective endocarditis. Panel A illustrates the initial surgical view of the heart with annotations for the right atrium (RA), left atrium (LA), and posterior mitral leaflet (PML). A large, irregular, whitish-tan vegetation is highlighted within a white oval, attached to the mitral valve apparatus. Surgical retractors and a suction vent tube are visible in the field. Panel B shows the surgical site following the partial resection of the PML. The white oval indicates residual vegetation on the mitral annulus. A white arrow points to a pseudoaneurysm located on the posterior wall of the left ventricle (LV), which resulted from a perforated valve annulus abscess. The image demonstrates the destructive nature of bacterial endocarditis on cardiac valves and adjacent myocardial tissue. These frames serve as educational material for cardiac surgeons and residents to understand the intraoperative presentation of complicated mitral valve endocarditis and associated paravalvular complications.

Two-panel intraoperative clinical photograph (A and B) showing findings during emergency cardiac surgery for infective endocarditis. Panel A illustrates the initial surgical view of the heart with annotations for the right atrium (RA), left atrium (LA), and posterior mitral leaflet (PML). A large, irregular, whitish-tan vegetation is highlighted within a white oval, attached to the mitral valve apparatus. Surgical retractors and a suction vent tube are visible in the field. Panel B shows the surgical site following the partial resection of the PML. The white oval indicates residual vegetation on the mitral annulus. A white arrow points to a pseudoaneurysm located on the posterior wall of the left ventricle (LV), which resulted from a perforated valve annulus abscess. The image demonstrates the destructive nature of bacterial endocarditis on cardiac valves and adjacent myocardial tissue. These frames serve as educational material for cardiac surgeons and residents to understand the intraoperative presentation of complicated mitral valve endocarditis and associated paravalvular complications.

Searching PubMed

"infective endocarditis"[MeSH Terms] AND treatment

Reading File
Reading File
Reading File
Reading File
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
I now have comprehensive information from multiple authoritative sources. Let me compile the full, well-structured answer.

Infective Endocarditis (IE): Basic to Clinical


Definition

Infective endocarditis is a microbial infection of the endocardial surface of the heart - primarily the cardiac valves - leading to formation of vegetations composed of thrombotic debris, inflammatory cells, and organisms. The aorta, aneurysmal sacs, prosthetic devices, and intracardiac electronic devices (pacemakers, defibrillators) may also be involved. Most cases are bacterial, though fungi (Candida, Aspergillus), rickettsiae (Q fever), and chlamydial species account for a minority of cases.
  • Robbins & Kumar Basic Pathology, p. 368

Classification

TypePaceOrganismValve
Acute IEDays - abrupt, destructiveS. aureus (virulent)Normal or diseased
Subacute IEWeeks to months - indolentViridans streptococci (less virulent)Pre-existing disease required

Epidemiology

  • Incidence: ~9-15 cases/100,000/year; 10,000-20,000 new cases/year in the US
  • 90-day mortality averages ~25%
  • Increasingly a disease of older adults, prosthetic valve recipients, IV drug users, and dialysis patients
  • Up to 36% of community-onset IE is healthcare-associated
  • IV drug use (IDU) accounts for 12%+ of cases in the US; opioid epidemic has accelerated this
  • Rosen's Emergency Medicine, p. 1549-1555

Pathogenesis (Basic Science)

The sequence of events follows three key steps:
  1. Endothelial/valve damage - from turbulent flow (valvular disease), prosthetic material, catheter trauma, or jet lesions from congenital shunts
  2. Sterile platelet-fibrin thrombus (NBTE) forms at the damaged site - a nidus for bacterial seeding
  3. Bacteremia seeds the thrombus - bacteria adhere, proliferate, and form a vegetation protected from host defenses
The vegetation consists of layered fibrin, platelets, bacteria, and inflammatory cells. In acute IE, the vegetations are large and destructive. In subacute IE, they tend to be smaller and more organized. Vegetations can:
  • Embolize distally (brain, kidneys, spleen, lungs, extremities)
  • Extend locally (perivalvular abscess, fistula, conduction block)
  • Trigger immune complex deposition
  • Robbins & Kumar Basic Pathology, p. 368-369

Causes and Microbiology

Native Valve IE (NVE)

OrganismSettingNotes
Viridans streptococci (S. mitis, S. sanguis, S. mutans)Community-acquired, SBENormal oral flora; damaged valves only
S. aureusHealthcare, IV drug use, ABEMost common in high-income countries; attacks normal valves
Enterococcus faecalisGenitourinary source; SBE5-10% of cases; GI screening recommended
S. gallolyticus (bovis)Elderly, SBEAssociated with colonic neoplasm - colonoscopy mandatory
HACEK groupCommunity, SBEH aemophilus, A ggregatibacter, C ardiobacterium, E ikenella, K ingella - 5-10%
Candida / AspergillusIDU, prolonged catheters, TPN, immunosuppressionHigh mortality; surgery usually required
Culture-negative (~10%)Prior antibiotic useDifficult-to-isolate organisms (Brucella, Coxiella, Bartonella)

Prosthetic Valve IE (PVE)

  • Early (<2 months): S. aureus, coagulase-negative staph, gram-negative bacilli, Candida - perioperative origin
  • Late (>2 months): Same as NVE spectrum
  • Goldman-Cecil Medicine, p. 703

IV Drug Use

  • Tricuspid valve most affected (~50%)
  • S. aureus is predominant pathogen
  • Rosen's Emergency Medicine, p. 1562

Risk Factors (Predisposing Conditions)

Higher risk:
  • Mitral valve prolapse (especially with regurgitation) - now the leading predisposing condition in developed countries
  • Prosthetic cardiac valves or prosthetic material used for repair (10-20% of all IE)
  • Previous episode of IE (high lifelong recurrence risk)
  • IV drug use
  • Congenital heart disease (bicuspid aortic valve, VSD, cyanotic CHD)
  • Degenerative valvular disease
  • Intravascular devices (pacemakers, ICD leads, central lines)
  • Chronic hemodialysis
Host factors increasing risk: Neutropenia, immunodeficiency, DM, malignancy, alcohol use
  • Goldman-Cecil Medicine, p. 700-701

Clinical Symptoms and Signs

Constitutional (almost universal)

  • Fever - the most consistent feature (>90% of patients)
  • Chills, rigors, sweats
  • Fatigue, malaise, anorexia, weight loss

Cardiac

  • Heart murmur - new or changing murmur (regurgitant) is hallmark
  • Signs of heart failure (dyspnea, orthopnea, pulmonary edema)
  • Pericardial friction rub (if pericarditis)
  • Conduction abnormalities (heart block) from perivalvular abscess

Embolic and Vascular Phenomena

  • Stroke or TIA (15-20% of patients; most common in mitral valve IE)
  • Septic pulmonary emboli (right-sided IE)
  • Splenic, renal, mesenteric infarction
  • Mycotic aneurysm (from infected emboli to arterial walls)

Peripheral Stigmata (classic but not always present)

SignDescriptionMechanism
PetechiaeSmall red/brown spots - skin, conjunctiva, oral mucosaEmbolic/vasculitic
Splinter hemorrhagesLinear dark streaks under nail bedsEmbolic
Osler nodesPainful, tender nodules on pads of fingers/toesImmune complex vasculitis
Janeway lesionsPainless hemorrhagic macules on palms/solesSeptic emboli
Roth spotsOval retinal hemorrhages with pale centers on fundoscopyImmune complex
ClubbingChronic, subacute cases
SplenomegalyMore common in subacute IE
Osler nodes = Painful (O = Ouch); Janeway = Not painful (J = "Just there")
Petechiae in infective endocarditis
Petechiae in infective endocarditis - Goldman-Cecil Medicine

Immune-Mediated

  • Arthralgias, myalgias
  • Glomerulonephritis (immune complex deposition)
  • Positive rheumatoid factor, false-positive syphilis serology
  • These are more prominent in subacute IE
  • Washington Manual of Medical Therapeutics, p. 530; Goldman-Cecil Medicine, p. 701

Diagnosis

1. Blood Cultures

  • The cornerstone - most reliable diagnostic criterion
  • 3 sets from separate venipuncture sites, 30 minutes apart, before antibiotics
  • Positive in ~90% of cases; ~10% culture-negative (prior antibiotics, fastidious organisms)

2. Echocardiography

  • Identifies vegetations, valve destruction, perivalvular abscess, and fistulas
  • TTE (transthoracic): First line; sensitivity 40-60%
  • TEE (transesophageal): More sensitive (~95%); indicated when TTE is negative but clinical suspicion is high, prosthetic valve involved, or poor image quality
  • Both should be performed in most patients
  • Braunwald's Heart Disease, p. 1237

3. Modified Duke Criteria (standard for diagnosis)

MAJOR Criteria:
  1. Positive blood cultures - typical organisms from 2 separate cultures (viridans strep, S. bovis, HACEK, S. aureus, or community-acquired enterococci without primary focus) OR persistently positive cultures >12 hrs apart
  2. Evidence of endocardial involvement - vegetation, abscess, or new valvular regurgitation on echo; or positive 18F-FDG PET/CT (added in updated criteria)
MINOR Criteria:
  1. Predisposing heart condition or IV drug use
  2. Fever >38°C
  3. Vascular phenomena (major arterial emboli, septic pulmonary emboli, mycotic aneurysm, intracranial hemorrhage, conjunctival hemorrhage, Janeway lesions)
  4. Immunologic phenomena (glomerulonephritis, Osler nodes, Roth spots, positive rheumatoid factor)
  5. Microbiologic evidence not meeting major criteria
Scoring:
  • Definite IE: 2 major, OR 1 major + 3 minor, OR 5 minor criteria
  • Possible IE: 1 major + 1 minor, OR 3 minor
  • Rejected: Alternative diagnosis, resolution of symptoms with antibiotics ≤4 days, no pathologic evidence at surgery/autopsy
Sensitivity 76-100%, specificity 88-100%, negative predictive value ≥92%.
  • Washington Manual of Medical Therapeutics, p. 528-530

4. Additional Investigations

  • CBC (leukocytosis, anemia of chronic disease)
  • ESR and CRP (elevated)
  • Urinalysis (hematuria, proteinuria, casts - from glomerulonephritis)
  • Chest X-ray (cardiomegaly, pulmonary edema, septic emboli)
  • ECG (conduction delays suggest perivalvular abscess)
  • CT/MRI brain (embolic stroke, mycotic aneurysm)

Echocardiographic Images

Vegetation on aortic valve - echocardiogram
Transthoracic echocardiogram showing vegetation (arrows) on the aortic valve leaflets in infective endocarditis
Gross pathology - mitral valve vegetations
Gross pathology specimen: friable vegetations (arrows) on the mitral valve leaflets with surrounding destruction

Treatment

General Principles

  • IE is a medical emergency requiring inpatient management
  • A multidisciplinary team (Infectious Disease + Cardiology + Cardiac Surgery) is essential
  • Start after obtaining 3 blood cultures - do not delay empirically if patient is hemodynamically unstable
  • IV antibiotics for 4-6 weeks (from the day bacteremia is cleared)
  • Monitor blood cultures daily until clearance is documented

Antibiotic Therapy (Organism-Directed)

OrganismDrugDuration
Viridans streptococci (PCN-sensitive)Penicillin G 12-18 MU/day IV or Ceftriaxone 2g/day4 weeks (NVE)
Viridans streptococci (PCN-resistant)Penicillin G or Ampicillin + Gentamicin4-6 weeks
MSSA (Native valve)Nafcillin/Oxacillin 12g/day IV6 weeks
MRSA (Native valve)Vancomycin 15 mg/kg IV q12h OR Daptomycin ≥8 mg/kg/day6 weeks
MSSA (Prosthetic valve)Oxacillin + Rifampin 300 mg PO q8h + Gentamicin≥6 weeks (gentamicin x 2 wk only)
MRSA/MRSE (Prosthetic valve)Vancomycin + Rifampin + Gentamicin≥6 weeks (gentamicin x 2 wk)
EnterococcusAmpicillin + Gentamicin (or Ampicillin + Ceftriaxone for synergy)4-6 weeks
HACEK organismsCeftriaxone 2g/day IV4 weeks NVE, 6 weeks PVE
FungalAmphotericin B + flucytosine; then azole suppressionValve surgery usually required
Culture-negativeConsult Infectious DiseasesEmpiric broad-spectrum
Vancomycin trough goal: 15-20 mcg/mL. Monitor audiometry weekly if aminoglycosides >7 days.
  • Washington Manual of Medical Therapeutics, p. 5651-5682

Surgical Indications (Emergency/Urgent)

Native Valve IE:
  • Heart failure not responsive to medical therapy (most common and most urgent indication)
  • Uncontrolled infection (persistent bacteremia, perivalvular abscess, fistula, increasing vegetation size)
  • Prevention of embolism (large mobile vegetation >10 mm, especially with prior embolic event)
Prosthetic Valve IE:
  • Valve dehiscence, obstruction, or severe regurgitation
  • S. aureus PVE or fungal PVE
  • All of the above
Right-Sided IE (IDU):
  • Surgery generally avoided unless medical therapy fails; right-sided IE has better prognosis
Key principle for neurologic complications: Delay surgery 3-4 weeks after major ischemic stroke; contraindicated within 1 month of hemorrhagic stroke.

Complications

ComplicationNotes
Heart failureMost common cause of death; aortic valve IE has highest risk
Perivalvular abscessS. aureus predominant; presents with new heart block or fever on therapy
Embolic stroke15-20% of patients; risk highest first 2 weeks
Septic emboliLungs (right-sided), kidneys, spleen, mesentery
Mycotic aneurysmIntracranial; risk of rupture and hemorrhage
Renal failureFrom emboli, immune complex nephritis, or drug toxicity
Metastatic infectionVertebral osteomyelitis, psoas abscess, meningitis
RelapseHigher risk with inadequate therapy or IV drug continuation

Prophylaxis (AHA 2021 Update)

Antibiotic prophylaxis before invasive dental procedures is recommended only for highest-risk patients:
  • Prosthetic cardiac valve or prosthetic material used for repair
  • Previous IE
  • Unrepaired cyanotic CHD or residual shunt/regurgitation after repair
  • Cardiac transplant with valvulopathy
  • Ventricular assist devices and implantable artificial hearts (added in 2021)
Preferred regimen: Amoxicillin 2g PO 30-60 minutes before procedure. For penicillin-allergic: doxycycline or azithromycin (clindamycin removed in 2021 due to C. difficile risk).
  • Braunwald's Heart Disease, p. 1232

Summary: Basic to Clinical Correlation

Basic Science ConceptClinical Correlation
NBTE (sterile thrombus on damaged valve)Predisposing cardiac conditions (MVP, rheumatic, bicuspid AV)
Bacterial adherence via surface proteinsViridans strep after dental work seeds damaged valves
Vegetation = fibrin + bacteria + inflammatory cellsEcho shows echogenic, mobile mass
Embolization of fragmentsStroke, renal infarct, septic pulmonary emboli
Immune complex depositionOsler nodes, Roth spots, glomerulonephritis, RF positive
Perivalvular extensionNew heart block on ECG, abscess on TEE, ring abscess at surgery
Bacteremia persistenceDaily blood cultures until clearance; fever on therapy = complication
Biofilm on prosthetic materialPVE needs rifampin (biofilm penetration) + longer therapy

Convert to pdf with same detail with drawings and with treatment plan also detail

Reading File
Running Command

mkdir -p /tmp/workspace/ie-pdf && ls /tmp/workspace/

Writing File

~/ie-pdf/generate_ie_pdf.py

#!/usr/bin/env python3
"""
Infective Endocarditis - Comprehensive Medical PDF
Full clinical guide: basic science to clinical management
"""

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_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, PageBreak, Image, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.graphics.shapes import Drawing, Rect, Circle, Line, String, Polygon, Ellipse
from reportlab.graphics import renderPDF
from reportlab.graphics.shapes import ArcPath
import math

# ─────────────────────────────────────────────
# COLORS
# ─────────────────────────────────────────────
DARK_BLUE   = colors.HexColor('#1A3A5C')
MED_BLUE    = colors.HexColor('#2563A8')
LIGHT_BLUE  = colors.HexColor('#D6E8FA')
TEAL        = colors.HexColor('#0D6E80')
LIGHT_TEAL  = colors.HexColor('#D0F0F4')
RED         = colors.HexColor('#C0392B')
LIGHT_RED   = colors.HexColor('#FDECEA')
ORANGE      = colors.HexColor('#E67E22')
LIGHT_ORANGE= colors.HexColor('#FEF3E2')
GREEN       = colors.HexColor('#1E8449')
LIGHT_GREEN = colors.HexColor('#D5F5E3')
YELLOW      = colors.HexColor('#F1C40F')
LIGHT_YELLOW= colors.HexColor('#FEFDE6')
PURPLE      = colors.HexColor('#6C3483')
LIGHT_PURPLE= colors.HexColor('#F0E6FA')
GRAY_BG     = colors.HexColor('#F4F6F9')
GRAY_BORDER = colors.HexColor('#BDC3C7')
WHITE       = colors.white
BLACK       = colors.black

PAGE_W, PAGE_H = A4

# ─────────────────────────────────────────────
# STYLES
# ─────────────────────────────────────────────
styles = getSampleStyleSheet()

def S(name, **kw):
    return ParagraphStyle(name, **kw)

cover_title = S('CoverTitle', fontSize=28, fontName='Helvetica-Bold',
                textColor=WHITE, alignment=TA_CENTER, leading=34)
cover_sub   = S('CoverSub',   fontSize=14, fontName='Helvetica',
                textColor=colors.HexColor('#B0D0F0'), alignment=TA_CENTER, leading=18)
cover_author= S('CoverAuthor',fontSize=11, fontName='Helvetica-Oblique',
                textColor=colors.HexColor('#90C0E0'), alignment=TA_CENTER)

h1_style = S('H1', fontSize=15, fontName='Helvetica-Bold',
             textColor=WHITE, alignment=TA_LEFT, leading=18,
             spaceBefore=8, spaceAfter=4,
             leftIndent=0, borderPadding=(6,10,6,10))

h2_style = S('H2', fontSize=12, fontName='Helvetica-Bold',
             textColor=DARK_BLUE, leading=15,
             spaceBefore=8, spaceAfter=3)

h3_style = S('H3', fontSize=10.5, fontName='Helvetica-Bold',
             textColor=TEAL, leading=13, spaceBefore=5, spaceAfter=2)

body_style = S('Body', fontSize=9.5, fontName='Helvetica',
               textColor=colors.HexColor('#2C3E50'), leading=14,
               spaceBefore=2, spaceAfter=2, alignment=TA_JUSTIFY)

bullet_style = S('Bullet', fontSize=9.5, fontName='Helvetica',
                 textColor=colors.HexColor('#2C3E50'), leading=14,
                 spaceBefore=1, spaceAfter=1,
                 leftIndent=14, firstLineIndent=-10)

caption_style = S('Caption', fontSize=8, fontName='Helvetica-Oblique',
                  textColor=colors.HexColor('#555555'), alignment=TA_CENTER,
                  spaceBefore=2, spaceAfter=6)

note_style = S('Note', fontSize=8.5, fontName='Helvetica-Oblique',
               textColor=colors.HexColor('#444444'), leading=12,
               leftIndent=10)

table_header = S('TH', fontSize=9, fontName='Helvetica-Bold',
                 textColor=WHITE, alignment=TA_CENTER, leading=11)
table_cell   = S('TC', fontSize=8.5, fontName='Helvetica',
                 textColor=BLACK, alignment=TA_LEFT, leading=11)
table_cell_c = S('TCC', fontSize=8.5, fontName='Helvetica',
                 textColor=BLACK, alignment=TA_CENTER, leading=11)

# ─────────────────────────────────────────────
# HELPER: Section Header Flowable
# ─────────────────────────────────────────────
class SectionHeader(Flowable):
    def __init__(self, text, bg_color=DARK_BLUE, text_color=WHITE, width=None, icon=None):
        super().__init__()
        self.text = text
        self.bg_color = bg_color
        self.text_color = text_color
        self._width = width or (PAGE_W - 4*cm)
        self.icon = icon
        self.height = 28

    def wrap(self, avail_w, avail_h):
        return self._width, self.height

    def draw(self):
        c = self.canv
        # Rounded rectangle background
        c.setFillColor(self.bg_color)
        c.roundRect(0, 0, self._width, self.height, 4, fill=1, stroke=0)
        # Left accent bar
        c.setFillColor(YELLOW)
        c.rect(0, 0, 5, self.height, fill=1, stroke=0)
        # Text
        c.setFillColor(self.text_color)
        c.setFont('Helvetica-Bold', 12)
        c.drawString(14, 8, self.text)


class SubHeader(Flowable):
    def __init__(self, text, bg_color=LIGHT_BLUE, text_color=DARK_BLUE, width=None):
        super().__init__()
        self.text = text
        self.bg_color = bg_color
        self.text_color = text_color
        self._width = width or (PAGE_W - 4*cm)
        self.height = 22

    def wrap(self, avail_w, avail_h):
        return self._width, self.height

    def draw(self):
        c = self.canv
        c.setFillColor(self.bg_color)
        c.roundRect(0, 0, self._width, self.height, 3, fill=1, stroke=0)
        c.setFillColor(MED_BLUE)
        c.rect(0, 0, 4, self.height, fill=1, stroke=0)
        c.setFillColor(self.text_color)
        c.setFont('Helvetica-Bold', 10.5)
        c.drawString(12, 6, self.text)


class InfoBox(Flowable):
    """Colored info/warning/note box"""
    def __init__(self, lines, color=LIGHT_BLUE, border_color=MED_BLUE, width=None, title=None):
        super().__init__()
        self.lines = lines
        self.color = color
        self.border_color = border_color
        self._width = width or (PAGE_W - 4*cm)
        self.title = title
        line_h = 14
        self.height = (len(lines) * line_h) + (20 if title else 10) + 10

    def wrap(self, avail_w, avail_h):
        return self._width, self.height

    def draw(self):
        c = self.canv
        c.setFillColor(self.color)
        c.setStrokeColor(self.border_color)
        c.setLineWidth(1.2)
        c.roundRect(0, 0, self._width, self.height, 4, fill=1, stroke=1)
        # Left accent
        c.setFillColor(self.border_color)
        c.rect(0, 0, 4, self.height, fill=1, stroke=0)
        y = self.height - 14
        if self.title:
            c.setFillColor(self.border_color)
            c.setFont('Helvetica-Bold', 9.5)
            c.drawString(12, y, self.title)
            y -= 16
        c.setFillColor(colors.HexColor('#1A1A2E'))
        c.setFont('Helvetica', 8.5)
        for line in self.lines:
            c.drawString(12, y, line)
            y -= 14

# ─────────────────────────────────────────────
# DIAGRAM 1: Pathogenesis Flow
# ─────────────────────────────────────────────
class PathogenesisDiagram(Flowable):
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 4*cm)
        self.height = 130

    def wrap(self, avail_w, avail_h):
        return self._width, self.height

    def draw(self):
        c = self.canv
        w = self._width
        # Background
        c.setFillColor(GRAY_BG)
        c.roundRect(0, 0, w, self.height, 6, fill=1, stroke=0)

        boxes = [
            ("Endothelial\nDamage", MED_BLUE, WHITE),
            ("Sterile\nThrombus\n(NBTE)", TEAL, WHITE),
            ("Bacteremia\nSeeding", ORANGE, WHITE),
            ("Vegetation\nFormation", RED, WHITE),
            ("Systemic\nComplications", PURPLE, WHITE),
        ]
        n = len(boxes)
        box_w = 70
        gap = (w - n * box_w) / (n + 1)
        box_h = 60
        y_box = (self.height - box_h) / 2

        for i, (label, bg, fg) in enumerate(boxes):
            x = gap + i * (box_w + gap)
            # Box
            c.setFillColor(bg)
            c.roundRect(x, y_box, box_w, box_h, 5, fill=1, stroke=0)
            # Text
            c.setFillColor(fg)
            c.setFont('Helvetica-Bold', 7.5)
            lines = label.split('\n')
            line_h = 10
            total_h = len(lines) * line_h
            y_text = y_box + box_h/2 + total_h/2 - line_h
            for line in lines:
                c.drawCentredString(x + box_w/2, y_text, line)
                y_text -= line_h
            # Number circle
            c.setFillColor(YELLOW)
            c.circle(x + box_w/2, y_box + box_h + 8, 8, fill=1, stroke=0)
            c.setFillColor(DARK_BLUE)
            c.setFont('Helvetica-Bold', 8)
            c.drawCentredString(x + box_w/2, y_box + box_h + 4.5, str(i+1))
            # Arrow
            if i < n - 1:
                ax = x + box_w + 4
                ay = y_box + box_h/2
                c.setStrokeColor(DARK_BLUE)
                c.setFillColor(DARK_BLUE)
                c.setLineWidth(1.5)
                c.line(ax, ay, ax + gap - 8, ay)
                # Arrowhead
                c.setFillColor(DARK_BLUE)
                p = c.beginPath()
                p.moveTo(ax + gap - 8, ay)
                p.lineTo(ax + gap - 14, ay + 4)
                p.lineTo(ax + gap - 14, ay - 4)
                p.close()
                c.drawPath(p, fill=1, stroke=0)

        # Title
        c.setFillColor(DARK_BLUE)
        c.setFont('Helvetica-Bold', 9)
        c.drawCentredString(w/2, self.height - 12, "PATHOGENESIS OF INFECTIVE ENDOCARDITIS")


# ─────────────────────────────────────────────
# DIAGRAM 2: Heart with IE sites
# ─────────────────────────────────────────────
class HeartDiagram(Flowable):
    def __init__(self, width=None):
        super().__init__()
        self._width = width or 260
        self.height = 220

    def wrap(self, avail_w, avail_h):
        return self._width, self.height

    def draw(self):
        c = self.canv
        w, h = self._width, self.height
        cx, cy = w/2, h/2 - 10

        # Background
        c.setFillColor(GRAY_BG)
        c.roundRect(0, 0, w, h, 6, fill=1, stroke=0)
        c.setFillColor(DARK_BLUE)
        c.setFont('Helvetica-Bold', 9)
        c.drawCentredString(w/2, h - 14, "HEART VALVES AFFECTED IN IE")

        # Heart outline (simplified)
        c.setFillColor(colors.HexColor('#FFB3B3'))
        c.setStrokeColor(RED)
        c.setLineWidth(1.5)
        # Left ventricle
        p = c.beginPath()
        p.moveTo(cx - 30, cy)
        p.curveTo(cx - 55, cy + 30, cx - 55, cy + 60, cx, cy + 80)
        p.curveTo(cx + 55, cy + 60, cx + 55, cy + 30, cx + 30, cy)
        p.lineTo(cx - 30, cy)
        c.drawPath(p, fill=1, stroke=1)

        # Atria
        c.setFillColor(colors.HexColor('#FFD0D0'))
        c.ellipse(cx - 50, cy + 10, cx - 10, cy + 50, fill=1, stroke=1)  # RA
        c.ellipse(cx + 10, cy + 10, cx + 50, cy + 50, fill=1, stroke=1)  # LA

        # Valve positions and labels
        valves = [
            (cx, cy + 28, "Mitral\nValve", MED_BLUE, 1),
            (cx, cy + 5,  "Aortic\nValve", RED, 2),
            (cx - 30, cy + 28, "Tricuspid\nValve", TEAL, 3),
            (cx + 30, cy + 28, "Pulmonary\nValve", GREEN, 4),
        ]

        for vx, vy, label, clr, num in valves:
            c.setFillColor(clr)
            c.circle(vx, vy, 7, fill=1, stroke=0)
            c.setFillColor(WHITE)
            c.setFont('Helvetica-Bold', 7)
            c.drawCentredString(vx, vy - 2.5, str(num))

        # Legend
        legend_items = [
            ("1 Mitral (most common - left-sided)", MED_BLUE),
            ("2 Aortic (worst prognosis)", RED),
            ("3 Tricuspid (IV drug users)", TEAL),
            ("4 Pulmonary (rare)", GREEN),
        ]
        lx, ly = 5, 68
        c.setFont('Helvetica-Bold', 7.5)
        c.setFillColor(DARK_BLUE)
        c.drawString(lx, ly + 4, "VALVE INVOLVEMENT:")
        ly -= 2
        for text, clr in legend_items:
            ly -= 14
            c.setFillColor(clr)
            c.circle(lx + 5, ly + 4, 5, fill=1, stroke=0)
            c.setFillColor(BLACK)
            c.setFont('Helvetica', 7.5)
            c.drawString(lx + 14, ly, text)


# ─────────────────────────────────────────────
# DIAGRAM 3: Clinical Features Wheel
# ─────────────────────────────────────────────
class ClinicalFeaturesDiagram(Flowable):
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 4*cm)
        self.height = 160

    def wrap(self, avail_w, avail_h):
        return self._width, self.height

    def draw(self):
        c = self.canv
        w = self._width
        # Background
        c.setFillColor(GRAY_BG)
        c.roundRect(0, 0, w, self.height, 6, fill=1, stroke=0)
        # Title
        c.setFillColor(DARK_BLUE)
        c.setFont('Helvetica-Bold', 9)
        c.drawCentredString(w/2, self.height - 12, "CLINICAL FEATURES AT A GLANCE")

        categories = [
            ("CONSTITUTIONAL\n(>90%)", ["Fever (most consistent)", "Chills/Rigors", "Night sweats", "Weight loss", "Fatigue, malaise"], MED_BLUE, LIGHT_BLUE),
            ("CARDIAC\nSIGNS", ["New/changing murmur", "Heart failure", "Pericardial rub", "Conduction block", "(from perivalvular\nabscess)"], TEAL, LIGHT_TEAL),
            ("PERIPHERAL\nSTIGMATA", ["Petechiae", "Splinter hemorrhages", "Osler nodes (painful)", "Janeway lesions (painless)", "Roth spots (fundus)", "Clubbing"], ORANGE, LIGHT_ORANGE),
            ("EMBOLIC\nEVENTS", ["Stroke/TIA (15-20%)", "Renal infarct", "Splenic infarct", "Septic pulm emboli\n(right-sided IE)", "Mycotic aneurysm"], RED, LIGHT_RED),
        ]
        n = len(categories)
        box_w = (w - 10) / n - 5
        box_h = 120
        y_start = 20

        for i, (title, items, fg, bg) in enumerate(categories):
            x = 5 + i * (box_w + 5)
            # Card background
            c.setFillColor(bg)
            c.setStrokeColor(fg)
            c.setLineWidth(1)
            c.roundRect(x, y_start, box_w, box_h, 4, fill=1, stroke=1)
            # Header
            c.setFillColor(fg)
            c.roundRect(x, y_start + box_h - 30, box_w, 30, 4, fill=1, stroke=0)
            c.setFillColor(fg)
            c.rect(x, y_start + box_h - 30, box_w, 15, fill=1, stroke=0)  # flat bottom
            c.setFillColor(WHITE)
            c.setFont('Helvetica-Bold', 7)
            title_lines = title.split('\n')
            ty = y_start + box_h - 14
            for tl in title_lines:
                c.drawCentredString(x + box_w/2, ty, tl)
                ty -= 10
            # Items
            c.setFillColor(colors.HexColor('#1A1A2E'))
            c.setFont('Helvetica', 7)
            iy = y_start + box_h - 36
            for item in items:
                if iy < y_start + 4:
                    break
                lines = item.split('\n')
                for ln in lines:
                    c.drawString(x + 8, iy, '• ' + ln if ln == lines[0] else '  ' + ln)
                    iy -= 11
                    if iy < y_start + 4:
                        break


# ─────────────────────────────────────────────
# DIAGRAM 4: Treatment Algorithm Flowchart
# ─────────────────────────────────────────────
class TreatmentFlowchart(Flowable):
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 4*cm)
        self.height = 320

    def wrap(self, avail_w, avail_h):
        return self._width, self.height

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

        c.setFillColor(GRAY_BG)
        c.roundRect(0, 0, w, h, 6, fill=1, stroke=0)
        c.setFillColor(DARK_BLUE)
        c.setFont('Helvetica-Bold', 9)
        c.drawCentredString(w/2, h - 14, "TREATMENT DECISION ALGORITHM")

        def box(x, y, bw, bh, text, bg, fg=WHITE, font_size=8):
            c.setFillColor(bg)
            c.setStrokeColor(colors.HexColor('#888888'))
            c.setLineWidth(0.5)
            c.roundRect(x, y, bw, bh, 4, fill=1, stroke=1)
            c.setFillColor(fg)
            c.setFont('Helvetica-Bold', font_size)
            lines = text.split('\n')
            total = len(lines) * (font_size + 2)
            ty = y + bh/2 + total/2 - (font_size + 2)
            for ln in lines:
                c.drawCentredString(x + bw/2, ty, ln)
                ty -= (font_size + 2)

        def diamond(x, y, bw, bh, text, bg=YELLOW, fg=DARK_BLUE):
            cx_ = x + bw/2
            cy_ = y + bh/2
            c.setFillColor(bg)
            c.setStrokeColor(DARK_BLUE)
            c.setLineWidth(0.8)
            p = c.beginPath()
            p.moveTo(cx_, y + bh)
            p.lineTo(x + bw, cy_)
            p.lineTo(cx_, y)
            p.lineTo(x, cy_)
            p.close()
            c.drawPath(p, fill=1, stroke=1)
            c.setFillColor(fg)
            c.setFont('Helvetica-Bold', 7.5)
            lines = text.split('\n')
            ty = cy_ + len(lines) * 4.5 - 4
            for ln in lines:
                c.drawCentredString(cx_, ty, ln)
                ty -= 10

        def arrow(x1, y1, x2, y2):
            c.setStrokeColor(DARK_BLUE)
            c.setFillColor(DARK_BLUE)
            c.setLineWidth(1.2)
            c.line(x1, y1, x2, y2)
            # arrowhead at end
            angle = math.atan2(y2-y1, x2-x1)
            ah = 7
            aw = 4
            c.setFillColor(DARK_BLUE)
            p = c.beginPath()
            p.moveTo(x2, y2)
            p.lineTo(x2 - ah*math.cos(angle) + aw*math.sin(angle),
                     y2 - ah*math.sin(angle) - aw*math.cos(angle))
            p.lineTo(x2 - ah*math.cos(angle) - aw*math.sin(angle),
                     y2 - ah*math.sin(angle) + aw*math.cos(angle))
            p.close()
            c.drawPath(p, fill=1, stroke=0)

        def label(x, y, text, clr=DARK_BLUE):
            c.setFillColor(clr)
            c.setFont('Helvetica-Bold', 7.5)
            c.drawString(x, y, text)

        # ---- LAYOUT ----
        top_y = h - 35
        bw_main = 160
        bx = (w - bw_main) / 2

        # Step 1
        box(bx, top_y - 30, bw_main, 26, "Suspected IE\n(Fever + Murmur / Risk Factors)", MED_BLUE)
        arrow(bx + bw_main/2, top_y - 30, bx + bw_main/2, top_y - 65)

        # Step 2
        box(bx, top_y - 91, bw_main, 26, "Obtain 3 Blood Cultures\n(separate sites, 30 min apart)", TEAL)
        arrow(bx + bw_main/2, top_y - 91, bx + bw_main/2, top_y - 126)

        # Step 3
        box(bx, top_y - 152, bw_main, 26, "Echocardiography\n(TTE first; TEE if negative)", TEAL)
        arrow(bx + bw_main/2, top_y - 152, bx + bw_main/2, top_y - 187)

        # Diamond: Duke Criteria
        diamond(bx + 10, top_y - 225, bw_main - 20, 36, "Modified Duke\nCriteria Met?")
        arrow(bx + bw_main/2, top_y - 225, bx + bw_main/2, top_y - 260)

        # Yes - Start antibiotics
        box(bx, top_y - 286, bw_main, 26, "Start IV Antibiotics\n(organism-directed, 4-6 wks)", GREEN)

        # No branch
        no_x = bx + bw_main + 15
        c.setStrokeColor(DARK_BLUE)
        c.setLineWidth(1.2)
        c.line(bx + bw_main - 10, top_y - 207, no_x + 70, top_y - 207)
        arrow(no_x + 70, top_y - 207, no_x + 70, top_y - 225)
        box(no_x, top_y - 251, 85, 26, "Possible IE -\nRepeat cultures\n& imaging", ORANGE, font_size=7)
        label(bx + bw_main + 2, top_y - 210, "NO", RED)
        label(bx + bw_main/2 - 12, top_y - 255, "YES", GREEN)

        # Surgery decision
        surgery_y = top_y - 315
        c.setStrokeColor(DARK_BLUE)
        c.setLineWidth(1.2)
        c.line(bx + bw_main/2, top_y - 286, bx + bw_main/2, surgery_y + 60)

        # Two branches at bottom
        surg_x1 = 5
        surg_x2 = w/2 + 10
        surg_bw = w/2 - 20

        c.line(bx + bw_main/2, surgery_y + 60, surg_x1 + surg_bw/2, surgery_y + 60)
        c.line(bx + bw_main/2, surgery_y + 60, surg_x2 + surg_bw/2, surgery_y + 60)
        arrow(surg_x1 + surg_bw/2, surgery_y + 60, surg_x1 + surg_bw/2, surgery_y + 36)
        arrow(surg_x2 + surg_bw/2, surgery_y + 60, surg_x2 + surg_bw/2, surgery_y + 36)

        box(surg_x1, surgery_y, surg_bw, 36,
            "MEDICAL Rx\nOnly\n(4-6 wks IV abx)", GREEN, font_size=7.5)
        box(surg_x2, surgery_y, surg_bw, 36,
            "SURGERY +\nMedical Rx\n(Valve repair/replace)", RED, font_size=7.5)

        label(surg_x1 + surg_bw/2 - 18, surgery_y + 40, "No surgery\nindications", colors.HexColor('#1A6620'))
        label(surg_x2 + surg_bw/2 - 20, surgery_y + 40, "Surgery\nindicated", RED)


# ─────────────────────────────────────────────
# DIAGRAM 5: Duke Criteria Visual
# ─────────────────────────────────────────────
class DukeCriteriaDiagram(Flowable):
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 4*cm)
        self.height = 155

    def wrap(self, avail_w, avail_h):
        return self._width, self.height

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

        c.setFillColor(GRAY_BG)
        c.roundRect(0, 0, w, self.height, 6, fill=1, stroke=0)
        c.setFillColor(DARK_BLUE)
        c.setFont('Helvetica-Bold', 9)
        c.drawCentredString(w/2, self.height - 12, "MODIFIED DUKE CRITERIA - VISUAL SUMMARY")

        # Major criteria box
        mc_x, mc_y = 5, 20
        mc_w = w*0.44
        mc_h = 110
        c.setFillColor(LIGHT_BLUE)
        c.setStrokeColor(MED_BLUE)
        c.setLineWidth(1.2)
        c.roundRect(mc_x, mc_y, mc_w, mc_h, 4, fill=1, stroke=1)
        c.setFillColor(MED_BLUE)
        c.roundRect(mc_x, mc_y + mc_h - 20, mc_w, 20, 4, fill=1, stroke=0)
        c.rect(mc_x, mc_y + mc_h - 20, mc_w, 10, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 8.5)
        c.drawCentredString(mc_x + mc_w/2, mc_y + mc_h - 14, "MAJOR CRITERIA (2 needed)")
        c.setFillColor(BLACK)
        c.setFont('Helvetica', 7.5)
        major = [
            "1. Positive blood cultures:",
            "   - Typical organism x2 separate cultures",
            "   - Viridans strep, S. bovis, HACEK,",
            "     S. aureus, Enterococcus (no primary focus)",
            "   - Persistently positive cultures >12h apart",
            "2. Endocardial involvement:",
            "   - Vegetation/abscess/new regurgitation on echo",
            "   - Positive 18F-FDG PET/CT (updated criteria)",
        ]
        ty = mc_y + mc_h - 28
        for line in major:
            c.drawString(mc_x + 6, ty, line)
            ty -= 10

        # Minor criteria box
        mn_x = mc_x + mc_w + 10
        mn_w = w - mn_x - 5
        c.setFillColor(LIGHT_TEAL)
        c.setStrokeColor(TEAL)
        c.roundRect(mn_x, mc_y, mn_w, mc_h, 4, fill=1, stroke=1)
        c.setFillColor(TEAL)
        c.roundRect(mn_x, mc_y + mc_h - 20, mn_w, 20, 4, fill=1, stroke=0)
        c.rect(mn_x, mc_y + mc_h - 20, mn_w, 10, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 8.5)
        c.drawCentredString(mn_x + mn_w/2, mc_y + mc_h - 14, "MINOR CRITERIA (3-5 needed)")
        c.setFillColor(BLACK)
        c.setFont('Helvetica', 7.5)
        minor = [
            "1. Predisposing valve/heart condition or IDU",
            "2. Fever >38°C",
            "3. Vascular phenomena:",
            "   (emboli, Janeway lesions, mycotic aneurysm,",
            "   intracranial hemorrhage)",
            "4. Immunologic phenomena:",
            "   (Osler nodes, Roth spots, RF positive, GN)",
            "5. Microbiologic: not meeting major criteria",
        ]
        ty = mc_y + mc_h - 28
        for line in minor:
            c.drawString(mn_x + 6, ty, line)
            ty -= 10

        # Scoring legend
        score_items = [
            ("DEFINITE: 2 Major  OR  1 Major + 3 Minor  OR  5 Minor", GREEN),
            ("POSSIBLE: 1 Major + 1 Minor  OR  3 Minor", ORANGE),
            ("REJECTED: Alternative diagnosis / Symptoms resolve ≤4d on abx", RED),
        ]
        c.setFont('Helvetica-Bold', 7.5)
        sx = 5
        sy = 16
        for text, clr in score_items:
            c.setFillColor(clr)
            c.rect(sx, sy - 1, 8, 8, fill=1, stroke=0)
            c.setFillColor(BLACK)
            c.setFont('Helvetica', 7)
            c.drawString(sx + 12, sy, text)
            sx += (w) // 3


# ─────────────────────────────────────────────
# DIAGRAM 6: Complication Map
# ─────────────────────────────────────────────
class ComplicationDiagram(Flowable):
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 4*cm)
        self.height = 145

    def wrap(self, avail_w, avail_h):
        return self._width, self.height

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

        c.setFillColor(GRAY_BG)
        c.roundRect(0, 0, w, self.height, 6, fill=1, stroke=0)
        c.setFillColor(DARK_BLUE)
        c.setFont('Helvetica-Bold', 9)
        c.drawCentredString(w/2, self.height - 12, "COMPLICATIONS MAP")

        # Center node
        cx, cy = w/2, self.height/2 - 8
        c.setFillColor(RED)
        c.circle(cx, cy, 28, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 8)
        c.drawCentredString(cx, cy + 4, "INFECTIVE")
        c.drawCentredString(cx, cy - 6, "ENDOCARDITIS")

        complications = [
            (cx - 100, cy + 60, "Heart\nFailure\n(#1 cause death)", RED),
            (cx + 100, cy + 60, "Perivalvular\nAbscess\n(heart block)", PURPLE),
            (cx - 120, cy,      "Embolic\nStroke\n(15-20%)", MED_BLUE),
            (cx + 120, cy,      "Septic\nEmboli\n(lungs, spleen)", TEAL),
            (cx - 100, cy - 60, "Mycotic\nAneurysm\n(rupture risk)", ORANGE),
            (cx + 100, cy - 60, "Renal\nFailure\n(GN / emboli)", colors.HexColor('#795548')),
        ]
        c.setFont('Helvetica-Bold', 7)
        for ex, ey, label, clr in complications:
            # Draw spoke
            c.setStrokeColor(clr)
            c.setLineWidth(1.2)
            dx = cx - ex; dy = cy - ey
            dist = (dx**2 + dy**2)**0.5
            ratio = 30 / dist
            c.line(cx - dx*ratio, cy - dy*ratio, ex + dx*0.28, ey + dy*0.28)
            # Node
            bw, bh = 70, 34
            c.setFillColor(clr)
            c.roundRect(ex - bw/2, ey - bh/2, bw, bh, 4, fill=1, stroke=0)
            c.setFillColor(WHITE)
            lines = label.split('\n')
            ty2 = ey + len(lines)*4
            for ln in lines:
                c.drawCentredString(ex, ty2, ln)
                ty2 -= 10


# ─────────────────────────────────────────────
# DOWNLOAD CLINICAL IMAGES
# ─────────────────────────────────────────────
def download_image(url, path):
    try:
        req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
        with urllib.request.urlopen(req, timeout=15) as resp:
            with open(path, 'wb') as f:
                f.write(resp.read())
        return True
    except Exception as e:
        print(f"  Image download failed {url}: {e}")
        return False

img_dir = '/tmp/workspace/ie-pdf/imgs'
os.makedirs(img_dir, exist_ok=True)

images = {
    'petechiae': ('https://cdn.orris.care/cdss_images/08c7790da4a166e7f1057c3e50834a12f2b268dbe140f0c1937b611b13bc9287.png',
                  'Petechiae in infective endocarditis (Goldman-Cecil Medicine)'),
    'osler':     ('https://cdn.orris.care/cdss_images/d68331a17f9f5dfd50561313ffefe6ad679d76490677de2a87a298fb744fc968.png',
                  'Osler node on finger in infective endocarditis (Goldman-Cecil Medicine)'),
    'echo_aortic':('https://cdn.orris.care/cdss_images/pmc_clinical_VQA_21611e4e2b613f3e8db5e51a70368da53410ac51ae91ccc38186cae1fbed7aa4.jpg',
                   'Transthoracic echocardiogram: vegetation on aortic valve (arrows)'),
    'gross_valve':('https://cdn.orris.care/cdss_images/pmc_clinical_VQA_f0f645951ff159780dab62d6de772480be7275751768b2e765c9318e166dffab.jpg',
                   'Gross pathology: mitral valve vegetations (friable, arrows) with leaflet destruction'),
}

print("Downloading clinical images...")
local_imgs = {}
for key, (url, cap) in images.items():
    path = os.path.join(img_dir, f'{key}.jpg' if url.endswith('.jpg') else f'{key}.png')
    if download_image(url, path):
        local_imgs[key] = (path, cap)
        print(f"  OK: {key}")
    else:
        local_imgs[key] = None

# ─────────────────────────────────────────────
# TABLE HELPERS
# ─────────────────────────────────────────────
def make_table(data, col_widths, header_bg=DARK_BLUE, alt_row=GRAY_BG, font_size=8.5):
    style = [
        ('BACKGROUND', (0,0), (-1,0), header_bg),
        ('TEXTCOLOR',  (0,0), (-1,0), WHITE),
        ('FONTNAME',   (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE',   (0,0), (-1,0), font_size),
        ('ALIGN',      (0,0), (-1,0), 'CENTER'),
        ('VALIGN',     (0,0), (-1,-1),'MIDDLE'),
        ('FONTNAME',   (0,1), (-1,-1),'Helvetica'),
        ('FONTSIZE',   (0,1), (-1,-1), font_size - 0.5),
        ('ROWBACKGROUND', (0,1), (-1,-1), [WHITE, alt_row]),
        ('GRID',       (0,0), (-1,-1), 0.4, GRAY_BORDER),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING',(0,0),(-1,-1), 4),
        ('LEFTPADDING', (0,0),(-1,-1), 5),
        ('RIGHTPADDING',(0,0),(-1,-1), 5),
    ]
    t = Table(data, colWidths=col_widths)
    t.setStyle(TableStyle(style))
    return t


def P(text, style=body_style):
    return Paragraph(text, style)

def B(text):
    return Paragraph('• ' + text, bullet_style)

def SP(h=0.2):
    return Spacer(1, h*cm)

# ─────────────────────────────────────────────
# BUILD PDF
# ─────────────────────────────────────────────
out_path = '/tmp/workspace/ie-pdf/Infective_Endocarditis_Complete_Guide.pdf'
doc = SimpleDocTemplate(
    out_path,
    pagesize=A4,
    rightMargin=2*cm, leftMargin=2*cm,
    topMargin=2*cm, bottomMargin=2*cm,
    title='Infective Endocarditis: Complete Clinical Guide',
    author='Orris Medical AI',
    subject='Basic to Clinical: IE Comprehensive Reference'
)

story = []

# ═══════════════════════════════════════════════════════
# COVER PAGE
# ═══════════════════════════════════════════════════════
class CoverPage(Flowable):
    def wrap(self, aw, ah):
        return aw, ah
    def draw(self):
        c = self.canv
        pw, ph = PAGE_W, PAGE_H
        # Background gradient effect
        for i in range(20):
            frac = i / 20
            r = 0.10 + frac * 0.05
            g = 0.23 + frac * 0.08
            b = 0.36 + frac * 0.15
            c.setFillColorRGB(r, g, b)
            c.rect(0, ph * (1 - (i+1)/20), pw, ph/20, fill=1, stroke=0)
        # Decorative circles
        c.setFillColor(colors.HexColor('#1E4A70'))
        c.circle(pw*0.85, ph*0.15, 80, fill=1, stroke=0)
        c.setFillColor(colors.HexColor('#163A5C'))
        c.circle(pw*0.1, ph*0.8, 60, fill=1, stroke=0)
        c.setFillColor(colors.HexColor('#0E2840'))
        c.circle(pw*0.75, ph*0.7, 40, fill=1, stroke=0)
        # Accent bar
        c.setFillColor(YELLOW)
        c.rect(0, ph*0.52, pw, 5, fill=1, stroke=0)
        c.setFillColor(colors.HexColor('#E67E22'))
        c.rect(0, ph*0.50, pw, 3, fill=1, stroke=0)
        # Main Title
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 36)
        c.drawCentredString(pw/2, ph*0.68, "INFECTIVE ENDOCARDITIS")
        c.setFont('Helvetica-Bold', 18)
        c.setFillColor(colors.HexColor('#B0D8F8'))
        c.drawCentredString(pw/2, ph*0.60, "Complete Clinical Reference")
        c.setFont('Helvetica', 13)
        c.setFillColor(colors.HexColor('#90C4E8'))
        c.drawCentredString(pw/2, ph*0.55, "Basic Science  ·  Clinical Presentation  ·  Diagnosis  ·  Treatment")
        # Bottom info block
        c.setFillColor(colors.HexColor('#0D1F30'))
        c.rect(0, 0, pw, ph*0.38, fill=1, stroke=0)
        topics = [
            ("Pathogenesis", "Microbiology", "Risk Factors"),
            ("Clinical Signs", "Duke Criteria", "Echocardiography"),
            ("Antibiotic Therapy", "Surgical Indications", "Prophylaxis"),
        ]
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 11)
        c.drawCentredString(pw/2, ph*0.36, "TOPICS COVERED")
        c.setFillColor(GRAY_BORDER)
        c.rect(pw*0.15, ph*0.346, pw*0.70, 0.5, fill=1, stroke=0)
        c.setFont('Helvetica', 9.5)
        c.setFillColor(colors.HexColor('#A0C4E0'))
        start_y = ph*0.32
        for row in topics:
            start_y -= 0.018*ph
            for j, topic in enumerate(row):
                x = pw * (0.2 + j * 0.22)
                c.setFillColor(MED_BLUE)
                c.circle(x - 8, start_y + 3, 3, fill=1, stroke=0)
                c.setFillColor(colors.HexColor('#C8E0F0'))
                c.drawString(x - 2, start_y, topic)
        # Source tag
        c.setFillColor(colors.HexColor('#607080'))
        c.setFont('Helvetica-Oblique', 8)
        c.drawCentredString(pw/2, ph*0.04, 'Sources: Robbins Pathology · Braunwald\'s Heart Disease · Goldman-Cecil Medicine · Washington Manual · Rosen\'s Emergency Medicine')
        c.drawCentredString(pw/2, ph*0.025, 'Generated by Orris Medical AI  ·  August 2026')

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

# ═══════════════════════════════════════════════════════
# SECTION 1: DEFINITION & CLASSIFICATION
# ═══════════════════════════════════════════════════════
story.append(SectionHeader("1.  DEFINITION & CLASSIFICATION"))
story.append(SP(0.3))
story.append(P(
    "<b>Infective endocarditis (IE)</b> is a microbial infection of the endocardial surface of the heart, "
    "primarily affecting cardiac valves. It leads to the formation of <b>vegetations</b> - masses composed of "
    "thrombotic debris, inflammatory cells, and organisms - often with destruction of the underlying cardiac tissue. "
    "Prosthetic valves, intracardiac devices (pacemakers, ICDs), aneurysmal sacs, and other vascular structures may also be involved."
))
story.append(SP(0.3))

class_data = [
    [P("Feature", table_header), P("Acute IE", table_header), P("Subacute IE", table_header)],
    [P("Onset", table_cell_c), P("Days - abrupt, rapidly progressive", table_cell), P("Weeks to months - insidious", table_cell)],
    [P("Typical Organism", table_cell_c), P("S. aureus (high virulence)", table_cell), P("Viridans streptococci (low virulence)", table_cell)],
    [P("Valve Requirement", table_cell_c), P("Can infect normal valves", table_cell), P("Requires pre-existing valve disease", table_cell)],
    [P("Destruction", table_cell_c), P("Severe, rapid valve destruction", table_cell), P("Slower, less destructive", table_cell)],
    [P("Morbidity/Mortality", table_cell_c), P("High even with therapy", table_cell), P("Most recover with appropriate antibiotics", table_cell)],
    [P("Immune Phenomena", table_cell_c), P("Less prominent", table_cell), P("More prominent (Osler nodes, RF, GN)", table_cell)],
]
cw = (PAGE_W - 4*cm) / 8
story.append(make_table(class_data, [cw*2, cw*3, cw*3]))
story.append(SP(0.2))
story.append(P('<i>Note: Many cases fall between acute and subacute - classification by causative organism, valve involved, and pace of illness is preferred.</i>', note_style))
story.append(SP(0.4))

# ═══════════════════════════════════════════════════════
# SECTION 2: EPIDEMIOLOGY
# ═══════════════════════════════════════════════════════
story.append(SectionHeader("2.  EPIDEMIOLOGY"))
story.append(SP(0.3))
epi_data = [
    ["Incidence", "~9-15 cases/100,000/year; 10,000-20,000 new US cases/year"],
    ["90-day Mortality", "~25% (worse with S. aureus, heart failure, perivalvular extension)"],
    ["Age Trend", "Increasingly a disease of older adults (>60 years)"],
    ["Healthcare-Associated", "Up to 36% of community-onset IE; linked to catheters, dialysis, procedures"],
    ["IV Drug Use", "7% (2000) → 12%+ (2013); >50% of cases in some communities (opioid epidemic)"],
    ["Prosthetic Valve IE", "Complicates up to 6% of valves; highest risk first 6 months post-surgery"],
    ["Right-Sided IE", "Tricuspid valve in ~50% of IDU cases; better prognosis than left-sided"],
]
cw2 = (PAGE_W - 4*cm) / 5
t2 = [[P(r[0], ParagraphStyle('TH2', fontSize=9, fontName='Helvetica-Bold', textColor=DARK_BLUE)),
        P(r[1], body_style)] for r in epi_data]
t2_tbl = Table(t2, colWidths=[cw2*1.5, cw2*3.5])
t2_tbl.setStyle(TableStyle([
    ('ROWBACKGROUNDS', (0,0), (-1,-1), [WHITE, GRAY_BG]),
    ('GRID', (0,0), (-1,-1), 0.4, GRAY_BORDER),
    ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
    ('TOPPADDING', (0,0), (-1,-1), 4),
    ('BOTTOMPADDING', (0,0), (-1,-1), 4),
    ('LEFTPADDING', (0,0), (-1,-1), 5),
]))
story.append(t2_tbl)
story.append(SP(0.4))

# ═══════════════════════════════════════════════════════
# SECTION 3: PATHOGENESIS
# ═══════════════════════════════════════════════════════
story.append(SectionHeader("3.  PATHOGENESIS (Basic Science)"))
story.append(SP(0.3))
story.append(PathogenesisDiagram())
story.append(SP(0.3))
patho_steps = [
    ("<b>Step 1 - Endothelial/Valve Damage:</b> Turbulent blood flow from valvular disease (MVP, bicuspid AV, rheumatic), "
     "prosthetic material, jet lesions from congenital shunts, or catheter trauma disrupts the valve endothelium, "
     "exposing subendothelial collagen."),
    ("<b>Step 2 - Sterile Thrombus (NBTE - Non-Bacterial Thrombotic Endocarditis):</b> Platelets and fibrin deposit "
     "on the exposed collagen, forming a sterile platelet-fibrin thrombus. This is the nidus for bacterial seeding."),
    ("<b>Step 3 - Bacteremia:</b> Microorganisms enter the bloodstream (dental procedures, skin infections, IV drug use, "
     "IV catheters, urogenital instrumentation, occult gut/oral flora). Even trivial activities can cause transient bacteremia."),
    ("<b>Step 4 - Vegetation Formation:</b> Bacteria adhere to the sterile thrombus via surface adhesins. They proliferate "
     "within the fibrin matrix, forming a <b>vegetation</b> - a layered structure of fibrin, platelets, bacteria, and "
     "inflammatory cells. Bacteria deep in the vegetation are protected from antibiotics and phagocytes, requiring prolonged therapy."),
    ("<b>Step 5 - Systemic Complications:</b> Vegetations can (a) embolize distally causing infarcts in the brain, "
     "kidneys, spleen, and lungs; (b) extend locally causing perivalvular abscesses, fistulas, and conduction defects; "
     "(c) trigger immune complex deposition causing nephritis, Osler nodes, and Roth spots."),
]
for step in patho_steps:
    story.append(B(step))
story.append(SP(0.4))

# ═══════════════════════════════════════════════════════
# SECTION 4: CAUSES & MICROBIOLOGY
# ═══════════════════════════════════════════════════════
story.append(SectionHeader("4.  CAUSES & MICROBIOLOGY"))
story.append(SP(0.3))
story.append(SubHeader("4a.  Native Valve IE (NVE)"))
story.append(SP(0.2))
micro_data = [
    [P("Organism", table_header), P("Clinical Setting", table_header), P("Course", table_header), P("Special Notes", table_header)],
    [P("Viridans Streptococci\n(S. mitis, S. sanguis, S. mutans)", table_cell),
     P("Community-acquired; oral flora after dental work", table_cell),
     P("Subacute", table_cell),
     P("Most common in developing countries; requires damaged valve", table_cell)],
    [P("S. aureus", table_cell),
     P("Healthcare-associated; IV drug users; skin infections", table_cell),
     P("Acute", table_cell),
     P("#1 cause in high-income countries; attacks normal valves; rapid destruction", table_cell)],
    [P("Enterococcus faecalis", table_cell),
     P("Community + nosocomial; GU source", table_cell),
     P("Subacute", table_cell),
     P("5-10% of cases; associated with GI neoplasm - screen colon", table_cell)],
    [P("S. gallolyticus (bovis)", table_cell),
     P("Elderly; community", table_cell),
     P("Subacute", table_cell),
     P("MANDATORY colonoscopy - strong association with colon cancer", table_cell)],
    [P("HACEK group\n(H/A/C/E/K)", table_cell),
     P("Community; oral cavity commensals", table_cell),
     P("Subacute", table_cell),
     P("5-10% of community IE; grow within 7 days in modern blood cultures", table_cell)],
    [P("Coagulase-negative Staph\n(S. epidermidis, S. lugdunensis)", table_cell),
     P("Prosthetic valves; healthcare", table_cell),
     P("Subacute", table_cell),
     P("S. lugdunensis: aggressive like S. aureus; high perivalvular extension", table_cell)],
    [P("Candida / Aspergillus", table_cell),
     P("IDU; TPN; prolonged catheters; immunosuppressed", table_cell),
     P("Subacute/chronic", table_cell),
     P("Very high mortality; Aspergillus rarely grows in blood cultures; surgery usually required", table_cell)],
    [P("Culture-negative (~10%)", table_cell),
     P("Prior antibiotics; Coxiella, Bartonella, Brucella", table_cell),
     P("Variable", table_cell),
     P("ID consultation essential; serologic testing needed", table_cell)],
]
cw3 = (PAGE_W - 4*cm) / 14
story.append(make_table(micro_data, [cw3*3, cw3*3, cw3*2, cw3*6]))
story.append(SP(0.3))
story.append(SubHeader("4b.  Prosthetic Valve IE (PVE)"))
story.append(SP(0.2))
pve_data = [
    [P("Timing", table_header), P("Definition", table_header), P("Common Organisms", table_header), P("Prognosis", table_header)],
    [P("Early PVE", table_cell_c), P("Within 2 months of surgery\n(perioperative seeding)", table_cell),
     P("S. aureus, CoNS, gram-negative bacilli, Candida", table_cell),
     P("Worse; high mortality", table_cell)],
    [P("Late PVE", table_cell_c), P(">2 months after surgery", table_cell),
     P("Same as NVE: S. aureus, viridans strep, enterococci", table_cell),
     P("Better than early", table_cell)],
]
story.append(make_table(pve_data, [cw3*2, cw3*3.5, cw3*5, cw3*3.5]))
story.append(SP(0.4))

# ═══════════════════════════════════════════════════════
# SECTION 5: RISK FACTORS
# ═══════════════════════════════════════════════════════
story.append(SectionHeader("5.  RISK FACTORS & PREDISPOSING CONDITIONS"))
story.append(SP(0.3))

rf_high = [
    "Mitral valve prolapse with regurgitation - <b>now the leading predisposing condition</b> in developed countries",
    "Previous episode of IE - confers high <b>lifelong risk</b> of recurrence",
    "Prosthetic cardiac valve or prosthetic valve repair material - accounts for <b>10-20% of all IE</b>",
    "IV drug use - endothelial damage + frequent bacteremia; tricuspid valve predominates",
    "Congenital heart disease: bicuspid aortic valve, VSD (especially uncorrected), cyanotic CHD",
    "Degenerative valvular disease (aortic stenosis, myxomatous mitral valve)",
    "Intravascular devices: pacemaker leads, ICD leads, central venous catheters, TAVI valves",
    "Chronic hemodialysis (arteriovenous fistulas reduce risk vs tunneled catheters)",
    "Ventricular assist devices and implantable artificial hearts (added as high-risk in AHA 2021)",
]
rf_host = [
    "Immunodeficiency (HIV, transplant, chemotherapy)",
    "Diabetes mellitus",
    "Malignancy (underlying GI neoplasm with S. bovis/gallolyticus)",
    "Chronic alcohol use",
    "Neutropenia",
]

story.append(SubHeader("High-Risk Cardiac Conditions"))
story.append(SP(0.15))
for r in rf_high:
    story.append(B(r))
story.append(SP(0.2))
story.append(SubHeader("Host Factors Increasing Risk"))
story.append(SP(0.15))
for r in rf_host:
    story.append(B(r))
story.append(SP(0.4))

# ═══════════════════════════════════════════════════════
# SECTION 6: CLINICAL FEATURES + IMAGES
# ═══════════════════════════════════════════════════════
story.append(SectionHeader("6.  CLINICAL SYMPTOMS & SIGNS"))
story.append(SP(0.3))
story.append(ClinicalFeaturesDiagram())
story.append(SP(0.3))

# Peripheral stigmata table with images
story.append(SubHeader("6a.  Peripheral Stigmata - Classic Signs"))
story.append(SP(0.2))
stig_data = [
    [P("Sign", table_header), P("Description", table_header), P("Mechanism", table_header), P("Clinical Pearl", table_header)],
    [P("Petechiae", table_cell_c),
     P("Small red/brown non-blanching spots; skin, conjunctivae, oral mucosa", table_cell),
     P("Embolic + vasculitic", table_cell),
     P("Most common peripheral sign", table_cell)],
    [P("Splinter Hemorrhages", table_cell_c),
     P("Linear dark streaks under nail bed, parallel to nail growth", table_cell),
     P("Septic microemboli", table_cell),
     P("Non-specific; also in 5-10% of healthy hospitalized patients", table_cell)],
    [P("Osler Nodes", table_cell_c),
     P("Painful, tender, red-purple nodules on pads of fingers/toes", table_cell),
     P("Immune complex vasculitis", table_cell),
     P("O = Ouch (painful). More common in subacute IE", table_cell)],
    [P("Janeway Lesions", table_cell_c),
     P("Painless, flat, hemorrhagic macules on palms and soles", table_cell),
     P("Septic emboli", table_cell),
     P("J = Just there (painless). More common in acute S. aureus IE", table_cell)],
    [P("Roth Spots", table_cell_c),
     P("Oval retinal hemorrhages with white/pale centers", table_cell),
     P("Immune complex vasculitis in retina", table_cell),
     P("Seen on fundoscopy; also in leukemia, anemia", table_cell)],
    [P("Clubbing", table_cell_c),
     P("Bulbous enlargement of fingertips; loss of nail bed angle", table_cell),
     P("Chronic hypoxia/inflammation", table_cell),
     P("Seen in prolonged subacute IE only", table_cell)],
    [P("Splenomegaly", table_cell_c),
     P("Enlarged, tender spleen", table_cell),
     P("Chronic infection + immune activation", table_cell),
     P("More common in subacute IE", table_cell)],
]
story.append(make_table(stig_data, [cw3*2.5, cw3*4, cw3*3, cw3*4.5]))
story.append(SP(0.4))

# Clinical images
story.append(SubHeader("6b.  Clinical and Imaging Findings"))
story.append(SP(0.2))

img_flow = []
for key in ['petechiae', 'osler', 'echo_aortic', 'gross_valve']:
    if local_imgs.get(key):
        path, cap = local_imgs[key]
        try:
            im = Image(path, width=7.5*cm, height=5.5*cm, kind='proportional')
            img_flow.append([im, P(cap, caption_style)])
        except:
            pass

if len(img_flow) >= 2:
    img_tbl = Table(
        [[img_flow[0][0], img_flow[1][0]],
         [img_flow[0][1], img_flow[1][1]]],
        colWidths=[(PAGE_W-4*cm)/2, (PAGE_W-4*cm)/2]
    )
    img_tbl.setStyle(TableStyle([
        ('ALIGN', (0,0), (-1,-1), 'CENTER'),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 4),
    ]))
    story.append(img_tbl)
    story.append(SP(0.2))

if len(img_flow) >= 4:
    img_tbl2 = Table(
        [[img_flow[2][0], img_flow[3][0]],
         [img_flow[2][1], img_flow[3][1]]],
        colWidths=[(PAGE_W-4*cm)/2, (PAGE_W-4*cm)/2]
    )
    img_tbl2.setStyle(TableStyle([
        ('ALIGN', (0,0), (-1,-1), 'CENTER'),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 4),
    ]))
    story.append(img_tbl2)

story.append(SP(0.4))

# ═══════════════════════════════════════════════════════
# SECTION 7: DIAGNOSIS
# ═══════════════════════════════════════════════════════
story.append(PageBreak())
story.append(SectionHeader("7.  DIAGNOSIS"))
story.append(SP(0.3))

story.append(SubHeader("7a.  Modified Duke Criteria"))
story.append(SP(0.2))
story.append(DukeCriteriaDiagram())
story.append(SP(0.3))

story.append(SubHeader("7b.  Diagnostic Workup"))
story.append(SP(0.2))
dx_data = [
    [P("Investigation", table_header), P("Findings in IE", table_header), P("Clinical Significance", table_header)],
    [P("Blood Cultures x3", table_cell_c),
     P("Positive in 90%; persistently positive in bacteremia", table_cell),
     P("CORNERSTONE - obtain before antibiotics; separate sites, 30 min apart", table_cell)],
    [P("TTE (Transthoracic Echo)", table_cell_c),
     P("Vegetation, valve regurgitation, abscess; sensitivity 40-60%", table_cell),
     P("First-line; negative TTE does NOT rule out IE if suspicion high", table_cell)],
    [P("TEE (Transesophageal Echo)", table_cell_c),
     P("Higher resolution; sensitivity ~95%", table_cell),
     P("Mandatory if TTE negative + high suspicion, prosthetic valve, or poor image quality", table_cell)],
    [P("CBC", table_cell_c),
     P("Leukocytosis (acute); normochromic anemia (subacute)", table_cell),
     P("Anemia of chronic disease common in subacute IE", table_cell)],
    [P("ESR / CRP", table_cell_c),
     P("Markedly elevated", table_cell),
     P("Non-specific but useful for monitoring treatment response", table_cell)],
    [P("Urinalysis", table_cell_c),
     P("Hematuria, proteinuria, RBC casts", table_cell),
     P("Immune complex glomerulonephritis (minor Duke criterion)", table_cell)],
    [P("ECG", table_cell_c),
     P("New PR prolongation, AV block, bundle branch block", table_cell),
     P("Suggests perivalvular extension / abscess - urgent TEE + surgery consult", table_cell)],
    [P("CT/MRI Brain", table_cell_c),
     P("Ischemic stroke, hemorrhagic transformation, mycotic aneurysm", table_cell),
     P("Performed if neurologic symptoms; mycotic aneurysm needs vascular surgery referral", table_cell)],
    [P("18F-FDG PET/CT", table_cell_c),
     P("Increased uptake at valve; detects extracardiac embolic foci", table_cell),
     P("Added as major Duke criterion in updated ESC/modified criteria; valuable in PVE", table_cell)],
    [P("Rheumatoid Factor", table_cell_c),
     P("False-positive (up to 50% in subacute IE)", table_cell),
     P("Minor Duke criterion - immunologic phenomenon", table_cell)],
]
story.append(make_table(dx_data, [cw3*2.5, cw3*5, cw3*6.5]))
story.append(SP(0.4))

# ═══════════════════════════════════════════════════════
# SECTION 8: TREATMENT
# ═══════════════════════════════════════════════════════
story.append(SectionHeader("8.  TREATMENT - COMPLETE PLAN"))
story.append(SP(0.3))
story.append(InfoBox(
    lines=[
        "IE requires INPATIENT management. A multidisciplinary team (Infectious Disease + Cardiology + Cardiac Surgery) is MANDATORY.",
        "ALWAYS obtain 3 blood cultures before starting antibiotics (unless hemodynamically unstable).",
        "Standard IV antibiotic course: 4-6 weeks, counting from the day bacteremia is confirmed cleared.",
        "Monitor blood cultures DAILY until clearance is documented.",
        "Clinical improvement typically seen within 3-10 days of initiating therapy.",
    ],
    color=LIGHT_BLUE,
    border_color=MED_BLUE,
    title="TREATMENT PRINCIPLES"
))
story.append(SP(0.3))
story.append(TreatmentFlowchart())
story.append(SP(0.3))

story.append(SubHeader("8a.  Antibiotic Therapy - Organism-Directed"))
story.append(SP(0.2))
abx_data = [
    [P("Organism", table_header), P("Regimen", table_header), P("Duration", table_header), P("Notes", table_header)],
    # Streptococci
    [P("Viridans Streptococci\n(PCN-sensitive MIC ≤0.12)", table_cell),
     P("Penicillin G 12-18 MU/day IV continuous OR\nCeftriaxone 2g IV/IM once daily", table_cell),
     P("4 weeks\n(NVE)", table_cell),
     P("Can use 2-week regimen with gentamicin if uncomplicated", table_cell)],
    [P("Viridans Streptococci\n(PCN-resistant MIC >0.12)", table_cell),
     P("Penicillin G or Ampicillin\n+ Gentamicin (3mg/kg/day in 3 doses)", table_cell),
     P("4-6 weeks", table_cell),
     P("Gentamicin for first 2 weeks only to limit nephrotoxicity", table_cell)],
    # S. aureus
    [P("S. aureus - MSSA\n(Native valve)", table_cell),
     P("Nafcillin or Oxacillin 12g/day IV (6 divided doses)\nOR Cefazolin 6g/day IV", table_cell),
     P("6 weeks", table_cell),
     P("DO NOT add routine gentamicin (no benefit, adds nephrotoxicity)", table_cell)],
    [P("S. aureus - MRSA\n(Native valve)", table_cell),
     P("Vancomycin 15-20 mg/kg IV q8-12h\nOR Daptomycin ≥8-10 mg/kg IV once daily", table_cell),
     P("6 weeks", table_cell),
     P("Vancomycin trough goal 15-20 mcg/mL; monitor CK with daptomycin", table_cell)],
    [P("S. aureus - MSSA\n(Prosthetic valve)", table_cell),
     P("Oxacillin/Nafcillin + Rifampin 300mg PO q8h\n+ Gentamicin 3mg/kg/day IV (2-3 doses)", table_cell),
     P("≥6 weeks\n(Gent x 2 wks only)", table_cell),
     P("Rifampin improves biofilm penetration; essential for prosthetic valves", table_cell)],
    [P("S. aureus - MRSA\n(Prosthetic valve)", table_cell),
     P("Vancomycin + Rifampin 300mg PO q8h\n+ Gentamicin 3mg/kg/day IV (2-3 doses)", table_cell),
     P("≥6 weeks\n(Gent x 2 wks only)", table_cell),
     P("Rifampin + gentamicin combo critical for PVE biofilm eradication", table_cell)],
    # Enterococcus
    [P("Enterococcus\n(PCN-sensitive)", table_cell),
     P("Ampicillin 12g/day IV + Gentamicin 3mg/kg/day\nOR Ampicillin 12g/day + Ceftriaxone 4g/day", table_cell),
     P("4-6 weeks", table_cell),
     P("Ampicillin-Ceftriaxone preferred in renal impairment (avoids aminoglycosides)", table_cell)],
    [P("Enterococcus - VRE", table_cell),
     P("Linezolid 600mg IV/PO q12h\nOR Daptomycin ≥8 mg/kg IV\n(ID consultation mandatory)", table_cell),
     P("≥6 weeks", table_cell),
     P("High treatment failure rate; surgical intervention often required", table_cell)],
    # HACEK
    [P("HACEK Group\nOrganisms", table_cell),
     P("Ceftriaxone 2g IV/IM once daily\nAlternatives: Ampicillin 12g/day or\nCiprofloxacin 400mg IV q12h", table_cell),
     P("4 weeks (NVE)\n6 weeks (PVE)", table_cell),
     P("Most HACEK organisms now beta-lactamase positive; avoid ampicillin alone", table_cell)],
    # Fungal
    [P("Fungal IE\n(Candida / Aspergillus)", table_cell),
     P("Amphotericin B liposomal 3-5mg/kg/day\n+ Flucytosine; then long-term azole suppression", table_cell),
     P("≥6 weeks + lifelong\nsuppression", table_cell),
     P("Surgery almost always required; Aspergillus rarely grows in blood cultures", table_cell)],
    # Culture-negative
    [P("Culture-Negative IE", table_cell),
     P("Consult Infectious Diseases urgently.\nConsider: Ceftriaxone + Ampicillin OR\nDoxycycline for Coxiella/Bartonella", table_cell),
     P("4-6 weeks\n(organism-dependent)", table_cell),
     P("Serologic testing for Coxiella (Q fever), Bartonella, Brucella; consider PCR of excised valve", table_cell)],
]
story.append(make_table(abx_data, [cw3*2.5, cw3*4.5, cw3*2, cw3*5]))
story.append(SP(0.3))

story.append(InfoBox(
    lines=[
        "Monitoring: Vancomycin trough goal 15-20 mcg/mL (or AUC/MIC 400-600).",
        "Aminoglycosides: Baseline + weekly audiometry if course >7 days. Monitor serum levels.",
        "Daptomycin: Monitor serum CK. Avoid if concurrent statins where possible.",
        "Rifampin: Never use alone (rapid resistance development); always combine.",
        "Oral switch: Can be considered in carefully selected stable patients after initial IV course (POET trial evidence).",
    ],
    color=LIGHT_YELLOW,
    border_color=ORANGE,
    title="MONITORING & SPECIAL CONSIDERATIONS"
))
story.append(SP(0.3))

# ═══════════════════════════════════════════════════════
# SECTION 8b: SURGICAL TREATMENT
# ═══════════════════════════════════════════════════════
story.append(SubHeader("8b.  Surgical Indications"))
story.append(SP(0.2))
surg_data = [
    [P("Indication", table_header), P("Timing", table_header), P("NVE", table_header), P("PVE", table_header)],
    [P("Acute heart failure from valve dysfunction", table_cell),
     P("EMERGENCY\n(same admission)", table_cell),
     P("Yes - most common\n& urgent indication", table_cell),
     P("Yes", table_cell)],
    [P("Perivalvular extension (abscess, fistula, new heart block)", table_cell),
     P("URGENT\n(within days)", table_cell),
     P("Yes", table_cell),
     P("Yes - very common in PVE", table_cell)],
    [P("Uncontrolled infection (persistent bacteremia >5-7 days despite adequate abx)", table_cell),
     P("URGENT", table_cell),
     P("Yes", table_cell),
     P("Yes", table_cell)],
    [P("Fungal or highly resistant organism (MRSA, VRE)", table_cell),
     P("URGENT", table_cell),
     P("Yes", table_cell),
     P("Yes - often required", table_cell)],
    [P("Large mobile vegetation >10mm + prior embolic event", table_cell),
     P("URGENT\n(within 24-48h)", table_cell),
     P("Yes", table_cell),
     P("Yes", table_cell)],
    [P("Very large vegetation >15mm (even without prior embolism)", table_cell),
     P("URGENT", table_cell),
     P("Consider", table_cell),
     P("Consider", table_cell)],
    [P("Increasing vegetation size on optimal antibiotics", table_cell),
     P("ELECTIVE/URGENT", table_cell),
     P("Consider", table_cell),
     P("Yes", table_cell)],
    [P("Valve dehiscence / obstruction / severe regurgitation (PVE)", table_cell),
     P("URGENT", table_cell),
     P("N/A", table_cell),
     P("Yes - hallmark PVE indication", table_cell)],
    [P("Right-sided IE (IDU)", table_cell),
     P("Elective (if fails medical therapy)", table_cell),
     P("Usually avoid\n(tricuspid valve IE)", table_cell),
     P("N/A", table_cell)],
]
story.append(make_table(surg_data, [cw3*4, cw3*2.5, cw3*2.5, cw3*5]))
story.append(SP(0.2))
story.append(InfoBox(
    lines=[
        "Neurologic complications: Delay surgery 3-4 weeks after major ISCHEMIC stroke.",
        "Hemorrhagic stroke: Surgery is CONTRAINDICATED within 1 month.",
        "Silent cerebral emboli (found on imaging only): Do NOT delay surgery.",
        "All IE patients should be managed at centers with expertise in cardiac surgery and ID.",
    ],
    color=LIGHT_RED,
    border_color=RED,
    title="SURGICAL TIMING - NEUROLOGIC COMPLICATIONS"
))
story.append(SP(0.4))

# ═══════════════════════════════════════════════════════
# SECTION 9: COMPLICATIONS
# ═══════════════════════════════════════════════════════
story.append(SectionHeader("9.  COMPLICATIONS"))
story.append(SP(0.3))
story.append(ComplicationDiagram())
story.append(SP(0.3))
comp_data = [
    [P("Complication", table_header), P("Frequency", table_header), P("Details & Management", table_header)],
    [P("Heart Failure", table_cell_c), P("30-40%", table_cell),
     P("Most common cause of death. Aortic valve IE has highest risk. Acute severe regurgitation → emergent surgery.", table_cell)],
    [P("Perivalvular Abscess", table_cell_c), P("20-40% (more in S. aureus)", table_cell),
     P("Presents with persistent fever, new conduction block on ECG. Requires TEE + urgent surgery.", table_cell)],
    [P("Embolic Stroke / TIA", table_cell_c), P("15-20%", table_cell),
     P("Most common in first 2 weeks; risk drops after 2 weeks of antibiotics. Mitral valve IE has highest stroke risk.", table_cell)],
    [P("Septic Pulmonary Emboli", table_cell_c), P("Common in right-sided IE", table_cell),
     P("Chest pain, hemoptysis, patchy infiltrates on CXR. Multiple cavitating lesions on CT.", table_cell)],
    [P("Mycotic Aneurysm", table_cell_c), P("2-10%", table_cell),
     P("Infected emboli lodge in vessel wall; intracranial location is most feared (rupture → hemorrhage). CT/MR angiography + vascular surgery.", table_cell)],
    [P("Glomerulonephritis", table_cell_c), P("Common in subacute IE", table_cell),
     P("Immune complex deposition. Hematuria, proteinuria, casts. Usually resolves with treatment.", table_cell)],
    [P("Metastatic Infection", table_cell_c), P("Variable", table_cell),
     P("Vertebral osteomyelitis, psoas abscess, meningitis, septic arthritis. Prolonged antibiotics + drainage as needed.", table_cell)],
    [P("Renal Failure", table_cell_c), P("10-20%", table_cell),
     P("From emboli, immune complex nephritis, or drug toxicity (aminoglycosides, vancomycin). Monitor creatinine.", table_cell)],
    [P("Relapse", table_cell_c), P("2-6%", table_cell),
     P("Risk higher with inadequate therapy, IV drug continuation, or resistant organisms. Full retreatment required.", table_cell)],
]
story.append(make_table(comp_data, [cw3*2.5, cw3*2, cw3*9.5]))
story.append(SP(0.4))

# ═══════════════════════════════════════════════════════
# SECTION 10: PROPHYLAXIS
# ═══════════════════════════════════════════════════════
story.append(SectionHeader("10.  PROPHYLAXIS (AHA 2021 Updated Guidelines)"))
story.append(SP(0.3))
story.append(P(
    "Antibiotic prophylaxis before <b>invasive dental procedures</b> is recommended ONLY for the highest-risk patients. "
    "The 2021 AHA update made several important changes from the 2007 guidelines:"
))
story.append(SP(0.15))
aha21 = [
    "<b>Added to high-risk list:</b> Ventricular assist devices and implantable artificial hearts",
    "<b>Eliminated clindamycin</b> as alternative (risk of Clostridioides difficile - potentially fatal)",
    "<b>Added doxycycline</b> as alternative for truly penicillin-allergic patients",
    "<b>Allergy screening:</b> 90% of patients reporting penicillin allergy have negative skin testing - amoxicillin can be used",
    "<b>Shared decision-making</b> with patient education regarding prophylaxis use",
    "<b>Oral hygiene:</b> Maintaining good oral health may reduce viridans streptococcal bacteremia from daily activities",
]
for a in aha21:
    story.append(B(a))
story.append(SP(0.2))

proph_data = [
    [P("High-Risk Group", table_header), P("Examples", table_header)],
    [P("Prosthetic cardiac valve / repair material", table_cell),
     P("Mechanical valve, bioprosthetic valve, TAVI valve, annuloplasty ring", table_cell)],
    [P("Previous infective endocarditis", table_cell),
     P("Any prior episode - lifetime prophylaxis", table_cell)],
    [P("Congenital heart disease (CHD)", table_cell),
     P("Unrepaired cyanotic CHD; Repaired CHD with residual shunt/regurgitation near prosthetic material", table_cell)],
    [P("Cardiac transplant with valvulopathy", table_cell),
     P("Valve disease developing after heart transplantation", table_cell)],
    [P("Ventricular assist devices (VAD)", table_cell),
     P("LVAD, RVAD, BiVAD, total artificial heart (added in 2021)", table_cell)],
]
story.append(make_table(proph_data, [cw3*4, cw3*10]))
story.append(SP(0.2))

story.append(SubHeader("Prophylaxis Regimens"))
story.append(SP(0.15))
reg_data = [
    [P("Situation", table_header), P("Drug", table_header), P("Dose & Timing", table_header)],
    [P("Oral / PCN-tolerant", table_cell_c),
     P("Amoxicillin (preferred)", table_cell),
     P("2g PO, 30-60 minutes before procedure", table_cell)],
    [P("Unable to take oral", table_cell_c),
     P("Ampicillin OR Cefazolin OR Ceftriaxone", table_cell),
     P("2g IM/IV (Ampicillin) or 1g IM/IV (Cefazolin/Ceftriaxone) 30-60 min before", table_cell)],
    [P("PCN/Ampicillin allergic\n(oral)", table_cell_c),
     P("Cephalexin OR Azithromycin OR Clarithromycin OR Doxycycline (NEW 2021)", table_cell),
     P("Cephalexin 2g PO; Azithromycin/Clarithromycin 500mg PO; Doxycycline 100mg PO", table_cell)],
    [P("PCN allergic\n(unable oral)", table_cell_c),
     P("Cefazolin OR Ceftriaxone", table_cell),
     P("1g IM/IV 30-60 min before", table_cell)],
]
story.append(make_table(reg_data, [cw3*2.5, cw3*4.5, cw3*7]))
story.append(SP(0.4))

# ═══════════════════════════════════════════════════════
# SECTION 11: BASIC-TO-CLINICAL CORRELATION TABLE
# ═══════════════════════════════════════════════════════
story.append(PageBreak())
story.append(SectionHeader("11.  BASIC SCIENCE TO CLINICAL CORRELATION"))
story.append(SP(0.3))
btc_data = [
    [P("Basic Science Concept", table_header), P("Clinical Correlate", table_header), P("Practical Implication", table_header)],
    [P("NBTE: sterile thrombus on\ndamaged endothelium", table_cell),
     P("Predisposing cardiac conditions (MVP, rheumatic, bicuspid AV)", table_cell),
     P("Screen at-risk patients; antibiotic prophylaxis for dental procedures", table_cell)],
    [P("Bacterial adhesins (FnBP, MSCRAMMs)\nbind collagen/fibrin matrix", table_cell),
     P("Viridans strep after dental work seeds damaged valves; S. aureus after IV access", table_cell),
     P("Dental hygiene, aseptic IV technique reduce IE incidence", table_cell)],
    [P("Vegetation = fibrin + platelets +\nbacteria + inflammatory cells", table_cell),
     P("Echogenic, mobile mass on echocardiogram with acoustic shadowing", table_cell),
     P("Echo is mandatory; TEE more sensitive for small/prosthetic valve vegetations", table_cell)],
    [P("Deep bacteria within biofilm:\nprotected from antibiotics", table_cell),
     P("Requires 4-6 weeks of HIGH-DOSE IV antibiotics", table_cell),
     P("Oral therapy generally inadequate; rifampin added for PVE biofilm penetration", table_cell)],
    [P("Vegetation fragments embolize\nto systemic circulation", table_cell),
     P("Stroke (15-20%), renal/splenic infarcts, septic pulmonary emboli", table_cell),
     P("Anticoagulation contraindicated; surgery if large vegetations (>10mm + prior emboli)", table_cell)],
    [P("Immune complex (IgG + complement)\ndeposition in microvasculature", table_cell),
     P("Osler nodes, Roth spots, glomerulonephritis, RF positive (minor Duke criteria)", table_cell),
     P("Seen predominantly in subacute IE; not a sign of active septic emboli", table_cell)],
    [P("Local extension of vegetation\nthrough annulus and myocardium", table_cell),
     P("New heart block on ECG; perivalvular abscess on TEE; ring abscess at surgery", table_cell),
     P("New PR prolongation = cardiac emergency - urgent TEE + surgery consult", table_cell)],
    [P("Persistent bacteremia with\nbiofilm-protected organisms", table_cell),
     P("Daily blood cultures until clearance; persistent fever on therapy = complication", table_cell),
     P("Fever after 72h on correct antibiotics: check for abscess, septic emboli, drug fever", table_cell)],
    [P("S. gallolyticus/bovis: colonic\nmucosa as portal of entry", table_cell),
     P("IE from this organism = mandatory GI screening", table_cell),
     P("Colonoscopy required in ALL S. gallolyticus/bovis IE and enterococcal IE", table_cell)],
    [P("Rickettsiae (Coxiella burnetti)\ndo not grow in standard culture", table_cell),
     P("Culture-negative IE in farmers, abattoir workers, rural setting", table_cell),
     P("Phase II Coxiella IgG titer >1:800 is a major Duke criterion (Q fever endocarditis)", table_cell)],
]
story.append(make_table(btc_data, [cw3*3.5, cw3*4.5, cw3*6]))
story.append(SP(0.4))

# ═══════════════════════════════════════════════════════
# SECTION 12: QUICK REFERENCE SUMMARY
# ═══════════════════════════════════════════════════════
story.append(SectionHeader("12.  QUICK REFERENCE SUMMARY"))
story.append(SP(0.3))
story.append(InfoBox(
    lines=[
        "DEFINITION: Microbial infection of cardiac valve endothelium → vegetation formation",
        "MOST COMMON CAUSE (high-income countries): Staphylococcus aureus",
        "MOST COMMON CAUSE (developing countries, community): Viridans streptococci",
        "MOST CONSISTENT SYMPTOM: Fever (>90%)",
        "GOLD STANDARD DIAGNOSIS: Blood culture + vegetation on echocardiography",
        "DIAGNOSIS CRITERIA: Modified Duke Criteria (sensitivity 76-100%, specificity 88-100%)",
        "FIRST-LINE ECHO: TTE; upgrade to TEE if TTE negative + high suspicion or prosthetic valve",
        "TREATMENT: Organism-directed IV antibiotics 4-6 weeks + multidisciplinary team",
        "MOST COMMON SURGERY INDICATION: Acute heart failure from valve dysfunction",
        "PROPHYLAXIS: AHA 2021 - amoxicillin 2g PO before invasive dental procedures (high-risk only)",
        "MORTALITY: ~25% at 90 days; worse with S. aureus, HF, perivalvular extension",
    ],
    color=LIGHT_BLUE,
    border_color=DARK_BLUE,
    title="KEY FACTS AT A GLANCE"
))
story.append(SP(0.3))

# References
story.append(HRFlowable(width='100%', thickness=0.5, color=GRAY_BORDER))
story.append(SP(0.2))
story.append(P("<b>SOURCES:</b>", h3_style))
refs = [
    "Robbins & Kumar Basic Pathology, 10th Ed. - Infective Endocarditis, p. 368-369",
    "Braunwald's Heart Disease, 12th Ed. (9780323722193) - Chapter 80G: IE Prevention, Diagnosis & Management",
    "Goldman-Cecil Medicine International Edition (9780323930345) - Chapter 61: Infective Endocarditis",
    "Washington Manual of Medical Therapeutics (9781975190620) - Chapter 14: Infective Endocarditis",
    "Rosen's Emergency Medicine (9780323757898) - Chapter 69: Infective Endocarditis",
    "AHA 2021 Scientific Statement: Prevention of Viridans Group Streptococcal Infective Endocarditis",
    "ESC Guidelines on Prevention, Diagnosis and Treatment of Infective Endocarditis (2023 update)",
    "Li JS et al. Proposed modifications to Duke criteria. Clin Infect Dis. 2000;30(4):633-638",
]
for ref in refs:
    story.append(P('• ' + ref, note_style))

story.append(SP(0.3))
story.append(P(
    '<i>Generated by Orris Medical AI · August 2026 · For educational purposes only. '
    'Always refer to current institutional guidelines and consult specialists for patient care decisions.</i>',
    caption_style
))

# ─────────────────────────────────────────────
# PAGE TEMPLATE WITH HEADER/FOOTER
# ─────────────────────────────────────────────
def on_page(canvas, document):
    canvas.saveState()
    # Header bar
    canvas.setFillColor(DARK_BLUE)
    canvas.rect(0, PAGE_H - 1.5*cm, PAGE_W, 1.5*cm, fill=1, stroke=0)
    canvas.setFillColor(YELLOW)
    canvas.rect(0, PAGE_H - 1.5*cm, 5, 1.5*cm, fill=1, stroke=0)
    canvas.setFillColor(WHITE)
    canvas.setFont('Helvetica-Bold', 9)
    canvas.drawString(1.5*cm, PAGE_H - 1.0*cm, "INFECTIVE ENDOCARDITIS  —  Complete Clinical Reference")
    canvas.setFont('Helvetica', 8)
    canvas.setFillColor(colors.HexColor('#A0C8E8'))
    canvas.drawRightString(PAGE_W - 1.5*cm, PAGE_H - 1.0*cm, "Orris Medical AI  ·  August 2026")
    # Footer
    canvas.setFillColor(GRAY_BG)
    canvas.rect(0, 0, PAGE_W, 1.2*cm, fill=1, stroke=0)
    canvas.setFillColor(MED_BLUE)
    canvas.rect(0, 1.2*cm, PAGE_W, 1.5, fill=1, stroke=0)
    canvas.setFillColor(DARK_BLUE)
    canvas.setFont('Helvetica', 7.5)
    canvas.drawString(1.5*cm, 0.45*cm,
        "Sources: Robbins Pathology · Braunwald's Heart Disease · Goldman-Cecil Medicine · Washington Manual · Rosen's Emergency Medicine")
    canvas.setFont('Helvetica-Bold', 8)
    canvas.drawRightString(PAGE_W - 1.5*cm, 0.45*cm, f"Page {document.page}")
    canvas.restoreState()

print("Building PDF...")
doc.build(story, onFirstPage=on_page, onLaterPages=on_page)
print(f"PDF saved to: {out_path}")
Running Command

cd /tmp/workspace/ie-pdf && python generate_ie_pdf.py 2>&1

Running Command

ls -lh /tmp/workspace/ie-pdf/Infective_Endocarditis_Complete_Guide.pdf

Your PDF is ready - 1.2 MB, A4 format, professionally designed.

Infective Endocarditis Complete Guide

PDF Document · PDF


Here is what the PDF contains across its pages:
Cover Page - Full-color designed cover with topic list and sources
12 Sections with diagrams, tables and clinical images:
  1. Definition & Classification - Acute vs Subacute IE comparison table
  2. Epidemiology - Incidence, mortality, trends, IDU impact
  3. Pathogenesis - Color-coded 5-step flow diagram (Endothelial Damage → NBTE → Bacteremia → Vegetation → Complications)
  4. Causes & Microbiology - Full tables for NVE and PVE organisms with clinical pearls
  5. Risk Factors - High-risk cardiac conditions and host factors
  6. Clinical Features - 4-panel feature cards diagram + peripheral stigmata table + 4 clinical images (petechiae, Osler node, echocardiogram, gross pathology)
  7. Diagnosis - Modified Duke Criteria visual diagram + full diagnostic workup table
  8. Treatment - Complete Plan - Treatment algorithm flowchart + organism-directed antibiotic table (all organisms including VRE, fungal, culture-negative) + monitoring box
  9. Surgical Indications - Emergency/Urgent/Elective categories with NVE vs PVE columns
  10. Complications - Spider-map diagram + detailed complications table
  11. Prophylaxis - AHA 2021 update with regimen table
  12. Basic-to-Clinical Correlation - 10-row table linking basic science to bedside findings + Quick Reference Summary

Infective endocarditis clinical symptoms causes and treatment and basic to clinical Start basic to clinical and convert into pdf

Reading File
Running Command

mkdir -p /tmp/workspace/ie-btc/imgs && echo "ready"

Use Harrison 21th edition with Infective endocarditis clinical symptoms causes and treatment and basic to clinical Start basic to clinical and convert into pdf

Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Searching Images

infective endocarditis peripheral signs Osler nodes Janeway lesions Roth spots splinter hemorrhage

This clinical photograph shows the palmar surface of a right hand, illustrating classic peripheral stigmata of infective endocarditis. The image displays multiple Janeway lesions, which appear as pink-to-red, macular, irregularly shaped, and non-tender hemorrhagic spots. These lesions are notably prominent on the distal phalanx of the thumb and the middle finger (indicated by arrows). Additionally, a clear subungual splinter hemorrhage is visible as a dark, linear longitudinal streak under the nail bed of the thumb (indicated by an arrowhead). The skin also shows signs of generalized dryness and scaling. These visual findings are critical clinical indicators of septic emboli or immunologic phenomena associated with systemic infection, specifically infective endocarditis. The photograph serves as an educational tool for recognizing vascular manifestations during a physical examination in an acute care or cardiology context.

This clinical photograph shows the palmar surface of a right hand, illustrating classic peripheral stigmata of infective endocarditis. The image displays multiple Janeway lesions, which appear as pink-to-red, macular, irregularly shaped, and non-tender hemorrhagic spots. These lesions are notably prominent on the distal phalanx of the thumb and the middle finger (indicated by arrows). Additionally, a clear subungual splinter hemorrhage is visible as a dark, linear longitudinal streak under the nail bed of the thumb (indicated by an arrowhead). The skin also shows signs of generalized dryness and scaling. These visual findings are critical clinical indicators of septic emboli or immunologic phenomena associated with systemic infection, specifically infective endocarditis. The photograph serves as an educational tool for recognizing vascular manifestations during a physical examination in an acute care or cardiology context.

This composite clinical photograph displays the physical findings of infective endocarditis manifest in the hands. Panel A shows a normal right palm for comparison. Panel B illustrates the left palm with multiple erythematous to violaceous lesions located on the thenar and hypothenar eminences. Panel C provides a magnified view of these palm lesions, distinguishing between Osler's nodes—small, raised, tender, reddish-purple nodules (marked with an arrow)—and Janeway lesions, which are flat, non-tender, erythematous macules (marked with an arrowhead). Panel D compares the nailbeds, highlighting a splinter hemorrhage on the left digit, characterized by a small, linear, dark-red streak beneath the nail plate, while the right nailbed appears normal. These peripheral stigmata are classic clinical indicators of septic emboli or immunological responses associated with systemic infections like endocarditis or infected arteriovenous fistulas.

This composite clinical photograph displays the physical findings of infective endocarditis manifest in the hands. Panel A shows a normal right palm for comparison. Panel B illustrates the left palm with multiple erythematous to violaceous lesions located on the thenar and hypothenar eminences. Panel C provides a magnified view of these palm lesions, distinguishing between Osler's nodes—small, raised, tender, reddish-purple nodules (marked with an arrow)—and Janeway lesions, which are flat, non-tender, erythematous macules (marked with an arrowhead). Panel D compares the nailbeds, highlighting a splinter hemorrhage on the left digit, characterized by a small, linear, dark-red streak beneath the nail plate, while the right nailbed appears normal. These peripheral stigmata are classic clinical indicators of septic emboli or immunological responses associated with systemic infections like endocarditis or infected arteriovenous fistulas.

This clinical photograph displays characteristic peripheral stigmata of infective endocarditis on a patient's hand. The primary findings are Osler's nodes, seen as painful, raised, violaceous nodular lesions located on the distal aspect of the fourth digit. These nodules exhibit a deep red-to-purple hue and appear slightly edematous, indicative of immune complex-mediated vasculitis. Additionally, the index finger displays splinter hemorrhages, visible as small, linear, dark reddish-brown streaks beneath the nail bed, representing micro-emboli or capillary damage. The middle finger is partially occluded by a patterned medical adhesive bandage. A healthcare provider in purple nitrile gloves is holding the hand, facilitating the clinical examination. These visual signs are critical diagnostic indicators for bacterial endocarditis, often associated with systemic bacteremia and valvular vegetations. The image serves as an educational tool for identifying classic dermatological manifestations of systemic cardiovascular infection.

This clinical photograph displays characteristic peripheral stigmata of infective endocarditis on a patient's hand. The primary findings are Osler's nodes, seen as painful, raised, violaceous nodular lesions located on the distal aspect of the fourth digit. These nodules exhibit a deep red-to-purple hue and appear slightly edematous, indicative of immune complex-mediated vasculitis. Additionally, the index finger displays splinter hemorrhages, visible as small, linear, dark reddish-brown streaks beneath the nail bed, representing micro-emboli or capillary damage. The middle finger is partially occluded by a patterned medical adhesive bandage. A healthcare provider in purple nitrile gloves is holding the hand, facilitating the clinical examination. These visual signs are critical diagnostic indicators for bacterial endocarditis, often associated with systemic bacteremia and valvular vegetations. The image serves as an educational tool for identifying classic dermatological manifestations of systemic cardiovascular infection.

This clinical photograph displays the palmar surface of a hand and fingers, highlighting classic dermatological manifestations of Janeway lesions. The image shows multiple, small, non-tender, erythematous macular rashes and hemorrhagic spots. These lesions are primarily distributed along the distal aspects of the fingers, specifically on the tips and pads. Morphologically, the lesions appear as flat, irregular, reddish-purple spots that do not involve significant skin elevation or surrounding edema. Clinically, these findings are pathognomonic for infective endocarditis, representing septic microemboli that lead to vascular injury and subcutaneous hemorrhage. The surrounding skin texture remains otherwise unremarkable, lacking signs of scaling or diffuse inflammation. This visual is an essential educational tool for identifying peripheral stigmata of systemic infection and differentiating painless Janeway lesions from painful, raised Osler nodules.

This clinical photograph displays the palmar surface of a hand and fingers, highlighting classic dermatological manifestations of Janeway lesions. The image shows multiple, small, non-tender, erythematous macular rashes and hemorrhagic spots. These lesions are primarily distributed along the distal aspects of the fingers, specifically on the tips and pads. Morphologically, the lesions appear as flat, irregular, reddish-purple spots that do not involve significant skin elevation or surrounding edema. Clinically, these findings are pathognomonic for infective endocarditis, representing septic microemboli that lead to vascular injury and subcutaneous hemorrhage. The surrounding skin texture remains otherwise unremarkable, lacking signs of scaling or diffuse inflammation. This visual is an essential educational tool for identifying peripheral stigmata of systemic infection and differentiating painless Janeway lesions from painful, raised Osler nodules.

Reading File
Searching Images

infective endocarditis echocardiogram vegetation mitral aortic valve

This composite figure presents clinical imaging and surgical findings of infective endocarditis. (A) Transthoracic echocardiogram (TTE) in a long-axis view shows a large, pedunculated echogenic vegetation (white arrow) measuring 1.75 cm x 1.10 cm attached to the anterior mitral valve leaflet. (B) TTE with color Doppler demonstrates a mosaic-pattern jet across the mitral valve, indicating severe mitral regurgitation. (C) Intraoperative view through the aorta (AO) reveals a yellowish vegetation (white arrow) infiltrating the aortic valve cusp. (D) Surgical exposure of the mitral valve via the right atrium (RA) shows extensive friable, yellowish vegetations (arrows) involving the anterior mitral cusp and annulus. (E) Gross specimen photograph displays the excised material on surgical gauze, with arrows pointing to the vegetations associated with the aortic valve (AV) and anterior mitral valve (AMV) tissue. The images collectively demonstrate the progression from diagnostic ultrasonography to surgical management of multi-valvular endocarditis, highlighting the morphology and destructive nature of infective vegetations.

This composite figure presents clinical imaging and surgical findings of infective endocarditis. (A) Transthoracic echocardiogram (TTE) in a long-axis view shows a large, pedunculated echogenic vegetation (white arrow) measuring 1.75 cm x 1.10 cm attached to the anterior mitral valve leaflet. (B) TTE with color Doppler demonstrates a mosaic-pattern jet across the mitral valve, indicating severe mitral regurgitation. (C) Intraoperative view through the aorta (AO) reveals a yellowish vegetation (white arrow) infiltrating the aortic valve cusp. (D) Surgical exposure of the mitral valve via the right atrium (RA) shows extensive friable, yellowish vegetations (arrows) involving the anterior mitral cusp and annulus. (E) Gross specimen photograph displays the excised material on surgical gauze, with arrows pointing to the vegetations associated with the aortic valve (AV) and anterior mitral valve (AMV) tissue. The images collectively demonstrate the progression from diagnostic ultrasonography to surgical management of multi-valvular endocarditis, highlighting the morphology and destructive nature of infective vegetations.

Two side-by-side transesophageal echocardiogram (TEE) images, labeled A and B, demonstrating infective endocarditis with valvular vegetations. Image A shows a grayscale ultrasound view of the mitral valve, with a yellow circle highlighting an irregular, heterogeneously echogenic mass (vegetation) attached to the mitral leaflet. Image B displays the aortic valve region, where a similar yellow circle indicates a lobulated, hyperechoic vegetation adherent to the aortic valve leaflets. Both structures exhibit typical characteristics of cardiac vegetations, including surface irregularities and moderate-to-high echogenicity relative to the myocardium. The surrounding valvular tissue in image B appears more disrupted, consistent with advanced infectious involvement. These diagnostic images are used to illustrate the visual manifestations of infective endocarditis, specifically the identification of vegetations on different heart valves, which are critical for confirming a clinical diagnosis of sepsis secondary to bacteremia.

Two side-by-side transesophageal echocardiogram (TEE) images, labeled A and B, demonstrating infective endocarditis with valvular vegetations. Image A shows a grayscale ultrasound view of the mitral valve, with a yellow circle highlighting an irregular, heterogeneously echogenic mass (vegetation) attached to the mitral leaflet. Image B displays the aortic valve region, where a similar yellow circle indicates a lobulated, hyperechoic vegetation adherent to the aortic valve leaflets. Both structures exhibit typical characteristics of cardiac vegetations, including surface irregularities and moderate-to-high echogenicity relative to the myocardium. The surrounding valvular tissue in image B appears more disrupted, consistent with advanced infectious involvement. These diagnostic images are used to illustrate the visual manifestations of infective endocarditis, specifically the identification of vegetations on different heart valves, which are critical for confirming a clinical diagnosis of sepsis secondary to bacteremia.

Running Command

mkdir -p /tmp/workspace/ie-harrison/imgs && echo "ready"

This is a shared conversation. Sign in to Orris to start your own chat.