attachment
attachment

Explain the management of CVA in simple words with additional information in a pdf format with some flowcharts and images also

Reading File
Reading File
analyse_media
Searching Images

ischemic stroke brain CT scan NCCT hemorrhage

This diagnostic imaging set consists of two axial CT slices of the brain, illustrating the clinical evaluation of an acute ischemic stroke. Panel A is a non-contrast CT (NCCT) scan, which provides a detailed view of the brain parenchyma, demonstrating the differentiation between grey and white matter, the ventricular system, and bony landmarks. It is primarily used in the acute setting to rule out intracranial hemorrhage. Panel B is a CT Angiogram (CTA) maximum intensity projection (MIP) image, which highlights the intracranial vasculature through contrast enhancement. The image reveals a focal vascular abnormality in the left hemisphere. Specifically, a red circle highlights a proximal occlusion or hyperdense embolus located in the M2 segment of the left middle cerebral artery (MCA). This comparison illustrates the transition from ruling out hemorrhage with NCCT to identifying large vessel occlusion (LVO) with CTA. These modalities are critical in determining eligibility for reperfusion therapies like tissue plasminogen activator (tPA) or mechanical thrombectomy.

This diagnostic imaging set consists of two axial CT slices of the brain, illustrating the clinical evaluation of an acute ischemic stroke. Panel A is a non-contrast CT (NCCT) scan, which provides a detailed view of the brain parenchyma, demonstrating the differentiation between grey and white matter, the ventricular system, and bony landmarks. It is primarily used in the acute setting to rule out intracranial hemorrhage. Panel B is a CT Angiogram (CTA) maximum intensity projection (MIP) image, which highlights the intracranial vasculature through contrast enhancement. The image reveals a focal vascular abnormality in the left hemisphere. Specifically, a red circle highlights a proximal occlusion or hyperdense embolus located in the M2 segment of the left middle cerebral artery (MCA). This comparison illustrates the transition from ruling out hemorrhage with NCCT to identifying large vessel occlusion (LVO) with CTA. These modalities are critical in determining eligibility for reperfusion therapies like tissue plasminogen activator (tPA) or mechanical thrombectomy.

This diagnostic comparison highlights a CT-occult minor stroke in the axial plane of the brain. The panel includes three images: (a) a non-contrast CT (NCCT), (b) a diffusion-weighted MRI (DWI, b=1000), and (c) a corresponding Apparent Diffusion Coefficient (ADC) map. In the NCCT image, the brain parenchyma appears normal without focal density changes or evidence of intracranial hemorrhage or large-vessel ischemia. In contrast, the DWI scan (b) reveals a distinct focal area of hyperintensity (bright signal) in the posterior limb of the right internal capsule, as indicated by the white arrow. This finding is matched in the ADC map (c) by a corresponding area of hypointensity (dark signal), confirming cytotoxic edema and restricted diffusion. This pattern is pathognomonic for an acute ischemic infarction. The comparison demonstrates the superior sensitivity of MRI short-protocols over standard CT for detecting small, acute lacunar or minor strokes in patients presenting with transient neurological symptoms like mild hemiparesis.

This diagnostic comparison highlights a CT-occult minor stroke in the axial plane of the brain. The panel includes three images: (a) a non-contrast CT (NCCT), (b) a diffusion-weighted MRI (DWI, b=1000), and (c) a corresponding Apparent Diffusion Coefficient (ADC) map. In the NCCT image, the brain parenchyma appears normal without focal density changes or evidence of intracranial hemorrhage or large-vessel ischemia. In contrast, the DWI scan (b) reveals a distinct focal area of hyperintensity (bright signal) in the posterior limb of the right internal capsule, as indicated by the white arrow. This finding is matched in the ADC map (c) by a corresponding area of hypointensity (dark signal), confirming cytotoxic edema and restricted diffusion. This pattern is pathognomonic for an acute ischemic infarction. The comparison demonstrates the superior sensitivity of MRI short-protocols over standard CT for detecting small, acute lacunar or minor strokes in patients presenting with transient neurological symptoms like mild hemiparesis.

**Imaging Modality:** Non-contrast Computed Tomography (NCCT) of the head.

**Imaging Modality:** Non-contrast Computed Tomography (NCCT) of the head.

Searching Images

cerebral angiography mechanical thrombectomy stroke

Educational panel illustrating endovascular management of an acute ischemic stroke. Panel A is a cerebral angiogram (digital subtraction angiography) demonstrating an acute occlusion of the left middle cerebral artery (MCA) at the M1 segment, evidenced by a sudden cutoff of contrast filling. Panel B is a clinical photograph of a mechanical thrombectomy specimen, showing a Solitaire stent retriever containing an entrapped red thrombus (clot) on a sterile field. Panel C is a post-thrombectomy cerebral angiogram showing successful TICI 3 recanalization, with restored contrast opacification throughout the distal MCA territory and its cortical branches. The composite demonstrates the sequence of diagnostic imaging, therapeutic intervention (mechanical thrombectomy), and clinical outcome in large vessel occlusion (LVO) stroke. This visual is relevant for neurology and neurointerventional radiology specialties for teaching vascular anatomy and stroke intervention protocols.

Educational panel illustrating endovascular management of an acute ischemic stroke. Panel A is a cerebral angiogram (digital subtraction angiography) demonstrating an acute occlusion of the left middle cerebral artery (MCA) at the M1 segment, evidenced by a sudden cutoff of contrast filling. Panel B is a clinical photograph of a mechanical thrombectomy specimen, showing a Solitaire stent retriever containing an entrapped red thrombus (clot) on a sterile field. Panel C is a post-thrombectomy cerebral angiogram showing successful TICI 3 recanalization, with restored contrast opacification throughout the distal MCA territory and its cortical branches. The composite demonstrates the sequence of diagnostic imaging, therapeutic intervention (mechanical thrombectomy), and clinical outcome in large vessel occlusion (LVO) stroke. This visual is relevant for neurology and neurointerventional radiology specialties for teaching vascular anatomy and stroke intervention protocols.

Cerebral imaging panel demonstrating acute ischemic stroke and its endovascular management. Panel A: Axial diffusion-weighted imaging (DWI) showing an area of hyperintensity (restricted diffusion) in the right putamen and corona radiata, consistent with acute infarction. Panel B: Time-of-flight magnetic resonance angiography (MRA) showing a signal void in the right internal carotid artery (ICA) and middle cerebral artery (MCA), indicating proximal occlusion. Panel C: Digital subtraction angiography (DSA) of the right carotid artery in lateral (LAT) view, confirming an abrupt cutoff at the cervical ICA. Panel D: Post-thrombectomy DSA in anterior-posterior (AP) view, demonstrating partial recanalization of the right ICA and restoration of distal intracranial flow. This sequence illustrates the radiological diagnosis of large vessel occlusion (LVO) and the immediate vascular outcome following mechanical thrombectomy in stroke neurology.

Cerebral imaging panel demonstrating acute ischemic stroke and its endovascular management. Panel A: Axial diffusion-weighted imaging (DWI) showing an area of hyperintensity (restricted diffusion) in the right putamen and corona radiata, consistent with acute infarction. Panel B: Time-of-flight magnetic resonance angiography (MRA) showing a signal void in the right internal carotid artery (ICA) and middle cerebral artery (MCA), indicating proximal occlusion. Panel C: Digital subtraction angiography (DSA) of the right carotid artery in lateral (LAT) view, confirming an abrupt cutoff at the cervical ICA. Panel D: Post-thrombectomy DSA in anterior-posterior (AP) view, demonstrating partial recanalization of the right ICA and restoration of distal intracranial flow. This sequence illustrates the radiological diagnosis of large vessel occlusion (LVO) and the immediate vascular outcome following mechanical thrombectomy in stroke neurology.

Digital subtraction angiography (DSA) images of the cerebral vasculature illustrating a left internal carotid artery (ICA) occlusion and the result of subsequent endovascular intervention. Panels A (coronal) and B (lateral) represent the pre-thrombectomy state, where black arrows indicate a sharp cutoff and total occlusion of the left ICA. There is a significant lack of contrast opacification in the distal middle cerebral artery (MCA) and anterior cerebral artery (ACA) territories, signifying severe ischemia. Panels C (coronal) and D (lateral) display the post-thrombectomy result, showing successful recanalization of the left ICA. These images demonstrate the restoration of blood flow with a dense, branching network of distal intracranial vessels now fully visualized. The comparison highlights the transition from a large vessel occlusion (LVO) to successful cerebral reperfusion. This material serves as an educational example of diagnostic angiography in acute ischemic stroke and the efficacy of mechanical thrombectomy in restoring cerebral perfusion.

Digital subtraction angiography (DSA) images of the cerebral vasculature illustrating a left internal carotid artery (ICA) occlusion and the result of subsequent endovascular intervention. Panels A (coronal) and B (lateral) represent the pre-thrombectomy state, where black arrows indicate a sharp cutoff and total occlusion of the left ICA. There is a significant lack of contrast opacification in the distal middle cerebral artery (MCA) and anterior cerebral artery (ACA) territories, signifying severe ischemia. Panels C (coronal) and D (lateral) display the post-thrombectomy result, showing successful recanalization of the left ICA. These images demonstrate the restoration of blood flow with a dense, branching network of distal intracranial vessels now fully visualized. The comparison highlights the transition from a large vessel occlusion (LVO) to successful cerebral reperfusion. This material serves as an educational example of diagnostic angiography in acute ischemic stroke and the efficacy of mechanical thrombectomy in restoring cerebral perfusion.

Finding Sources
Running Command

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

Writing File

~/cva-pdf/build_cva_pdf.py

#!/usr/bin/env python3
"""
CVA (Cerebrovascular Accident) Management - Comprehensive PDF
Uses ReportLab for PDF generation with flowcharts, images, and clean layout.
"""

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, KeepTogether, Image as RLImage
)
from reportlab.platypus.flowables import Flowable
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Polygon, Circle, Path
from reportlab.graphics import renderPDF
from reportlab.graphics.shapes import Group
from reportlab.pdfgen import canvas
from io import BytesIO
import math

# ── Color palette ────────────────────────────────────────────────────────────
DARK_BLUE   = colors.HexColor("#1A3A5C")
MED_BLUE    = colors.HexColor("#2E6DA4")
LIGHT_BLUE  = colors.HexColor("#D6E8F7")
RED         = colors.HexColor("#C0392B")
LIGHT_RED   = colors.HexColor("#FADBD8")
GREEN       = colors.HexColor("#1E7A4A")
LIGHT_GREEN = colors.HexColor("#D5F5E3")
ORANGE      = colors.HexColor("#E67E22")
LIGHT_ORANGE= colors.HexColor("#FDEBD0")
YELLOW      = colors.HexColor("#F1C40F")
LIGHT_YELLOW= colors.HexColor("#FEF9E7")
PURPLE      = colors.HexColor("#6C3483")
LIGHT_PURPLE= colors.HexColor("#E8DAEF")
GRAY        = colors.HexColor("#7F8C8D")
LIGHT_GRAY  = colors.HexColor("#F2F3F4")
WHITE       = colors.white
BLACK       = colors.black

PAGE_W, PAGE_H = A4
MARGIN = 1.8 * cm

# ── Download images ───────────────────────────────────────────────────────────
IMG_URLS = {
    "ncct_stroke": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_4be9040832cdece09862288ff0e88ec41b2c86bd13b42a53293cbb527bc893fd.jpg",
    "thrombectomy": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_24e68df4e5c7474c56abf5e8344ad92dc24b8f27c8708c51e73f7dbb0a5e4b43.jpg",
    "mri_stroke":   "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_2d40a69969282276f8ac003805afcd0cd9fa2fa4c87824e1b32640869b402d3a.jpg",
}
img_paths = {}
for key, url in IMG_URLS.items():
    path = f"/tmp/workspace/cva-pdf/{key}.jpg"
    try:
        urllib.request.urlretrieve(url, path)
        img_paths[key] = path
        print(f"Downloaded: {key}")
    except Exception as e:
        print(f"Failed {key}: {e}")

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

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

Title_S   = make_style("Title_S",   fontSize=28, textColor=WHITE,        alignment=TA_CENTER, spaceAfter=4, fontName="Helvetica-Bold")
Sub_S     = make_style("Sub_S",     fontSize=13, textColor=LIGHT_BLUE,   alignment=TA_CENTER, spaceAfter=2, fontName="Helvetica")
H1_S      = make_style("H1_S",      fontSize=16, textColor=WHITE,        alignment=TA_CENTER, spaceAfter=6, fontName="Helvetica-Bold")
H2_S      = make_style("H2_S",      fontSize=13, textColor=DARK_BLUE,    spaceAfter=4,        fontName="Helvetica-Bold", spaceBefore=8)
H3_S      = make_style("H3_S",      fontSize=11, textColor=MED_BLUE,     spaceAfter=3,        fontName="Helvetica-Bold", spaceBefore=4)
Body_S    = make_style("Body_S",    fontSize=10, textColor=BLACK,        spaceAfter=3,        leading=14, alignment=TA_JUSTIFY)
Bullet_S  = make_style("Bullet_S",  fontSize=10, textColor=BLACK,        spaceAfter=2,        leading=14, leftIndent=12, bulletIndent=2)
Caption_S = make_style("Caption_S", fontSize=8,  textColor=GRAY,        alignment=TA_CENTER, spaceAfter=4, fontName="Helvetica-Oblique")
Box_S     = make_style("Box_S",     fontSize=10, textColor=DARK_BLUE,   spaceAfter=2,        leading=14, leftIndent=6)
Warn_S    = make_style("Warn_S",    fontSize=10, textColor=RED,          spaceAfter=2,        leading=14, leftIndent=6, fontName="Helvetica-Bold")
Small_S   = make_style("Small_S",   fontSize=8,  textColor=GRAY,        spaceAfter=1,        leading=11)
Center_S  = make_style("Center_S",  fontSize=10, alignment=TA_CENTER,   spaceAfter=2,        leading=14)


# ── Helper flowables ──────────────────────────────────────────────────────────
class ColoredBox(Flowable):
    """A rounded colored box containing text."""
    def __init__(self, text, bg=LIGHT_BLUE, border=MED_BLUE, text_color=DARK_BLUE,
                 width=None, height=None, font_size=10, bold=False, padding=8, radius=6):
        super().__init__()
        self.text = text
        self.bg = bg
        self.border = border
        self.text_color = text_color
        self.box_width = width or (PAGE_W - 2*MARGIN)
        self.box_height = height
        self.font_size = font_size
        self.bold = bold
        self.padding = padding
        self.radius = radius

    def wrap(self, availW, availH):
        self.width = self.box_width
        self.height = self.box_height or (self.font_size + 2*self.padding + 4)
        return self.width, self.height

    def draw(self):
        c = self.canv
        c.saveState()
        c.setFillColor(self.bg)
        c.setStrokeColor(self.border)
        c.setLineWidth(1.5)
        c.roundRect(0, 0, self.width, self.height, self.radius, fill=1, stroke=1)
        c.setFillColor(self.text_color)
        font = "Helvetica-Bold" if self.bold else "Helvetica"
        c.setFont(font, self.font_size)
        c.drawCentredString(self.width/2, self.height/2 - self.font_size*0.35, self.text)
        c.restoreState()


class Arrow(Flowable):
    """Downward arrow."""
    def __init__(self, color=MED_BLUE, width=30, height=20):
        super().__init__()
        self.arrow_color = color
        self.arrow_width = width
        self.arrow_height = height

    def wrap(self, availW, availH):
        self.width = availW
        self.height = self.arrow_height
        return self.width, self.height

    def draw(self):
        c = self.canv
        c.saveState()
        c.setFillColor(self.arrow_color)
        c.setStrokeColor(self.arrow_color)
        cx = self.width / 2
        shaft_w = 4
        arrow_w = 14
        h = self.arrow_height
        # shaft
        c.rect(cx - shaft_w/2, h*0.35, shaft_w, h*0.55, fill=1, stroke=0)
        # arrowhead
        c.beginPath()
        c.moveTo(cx - arrow_w/2, h*0.35)
        c.lineTo(cx + arrow_w/2, h*0.35)
        c.lineTo(cx, 2)
        c.closePath()
        c.fill()
        c.restoreState()


def section_header(title, color=DARK_BLUE, bg=MED_BLUE):
    """Returns a table acting as a section header bar."""
    data = [[Paragraph(title, H1_S)]]
    t = Table(data, colWidths=[PAGE_W - 2*MARGIN])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("ROUNDEDCORNERS", [8,8,8,8]),
        ("TOPPADDING", (0,0), (-1,-1), 10),
        ("BOTTOMPADDING", (0,0), (-1,-1), 10),
        ("LEFTPADDING", (0,0), (-1,-1), 14),
        ("RIGHTPADDING", (0,0), (-1,-1), 14),
    ]))
    return t


def info_box(rows, bg=LIGHT_BLUE, border=MED_BLUE, title=None, title_bg=MED_BLUE):
    """A styled info box with optional title and bullet rows."""
    content = []
    if title:
        content.append([Paragraph(f"<b>{title}</b>", make_style("_t", fontSize=11, textColor=WHITE, fontName="Helvetica-Bold"))])
    for r in rows:
        content.append([Paragraph(r, Box_S)])
    col_w = PAGE_W - 2*MARGIN
    t = Table(content, colWidths=[col_w])
    ts = [
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("LINEBELOW", (0,0), (-1,-1), 0.3, border),
        ("TOPPADDING", (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING", (0,0), (-1,-1), 10),
        ("RIGHTPADDING", (0,0), (-1,-1), 10),
        ("BOX", (0,0), (-1,-1), 1.5, border),
    ]
    if title:
        ts += [
            ("BACKGROUND", (0,0), (0,0), title_bg),
        ]
    t.setStyle(TableStyle(ts))
    return t


# ── FLOWCHART DRAWINGS ────────────────────────────────────────────────────────

def make_befast_chart():
    """BE-FAST recognition diagram."""
    W, H = PAGE_W - 2*MARGIN, 4.5*cm
    d = Drawing(W, H)
    
    letters = [
        ("B", "Balance\nProblems",    "#E74C3C"),
        ("E", "Eye\nBlurring",        "#E67E22"),
        ("F", "Facial\nAsymmetry",    "#F39C12"),
        ("A", "Arm\nWeakness",        "#27AE60"),
        ("S", "Speech\nDeficit",      "#2980B9"),
        ("T", "Time\nIs Critical",    "#8E44AD"),
    ]
    
    box_w = (W - 10) / 6
    box_h = H - 10
    
    for i, (letter, desc, hex_col) in enumerate(letters):
        x = i * (box_w + 2)
        col = colors.HexColor(hex_col)
        light = colors.HexColor(hex_col + "33") if len(hex_col) == 7 else col
        
        # box
        d.add(Rect(x, 5, box_w, box_h, rx=6, ry=6,
                   fillColor=col, strokeColor=col,
                   strokeWidth=0))
        # letter
        d.add(String(x + box_w/2, box_h - 10, letter,
                     fontName="Helvetica-Bold", fontSize=22,
                     fillColor=WHITE, textAnchor="middle"))
        # description lines
        for j, line in enumerate(desc.split("\n")):
            d.add(String(x + box_w/2, box_h - 26 - j*13, line,
                         fontName="Helvetica", fontSize=7.5,
                         fillColor=WHITE, textAnchor="middle"))
    return d


def make_main_flowchart():
    """Main CVA management decision flowchart."""
    W = PAGE_W - 2*MARGIN
    H = 22*cm
    d = Drawing(W, H)
    
    cx = W / 2
    
    def box(x, y, w, h, text, bg, border, text_color=WHITE, font_size=9, bold=True, radius=6):
        d.add(Rect(x, y, w, h, rx=radius, ry=radius,
                   fillColor=bg, strokeColor=border, strokeWidth=1.5))
        font = "Helvetica-Bold" if bold else "Helvetica"
        lines = text.split("\n")
        total_h = len(lines) * (font_size + 2)
        start_y = y + h/2 + total_h/2 - font_size
        for i, line in enumerate(lines):
            d.add(String(x + w/2, start_y - i*(font_size+2), line,
                         fontName=font, fontSize=font_size,
                         fillColor=text_color, textAnchor="middle"))
    
    def arrow_down(x, y1, y2, color=MED_BLUE):
        d.add(Line(x, y1, x, y2+8, strokeColor=color, strokeWidth=2))
        # arrowhead
        d.add(Polygon([x-5, y2+8, x+5, y2+8, x, y2],
                      fillColor=color, strokeColor=color, strokeWidth=0))
    
    def arrow_right(x1, x2, y, color=MED_BLUE, label=""):
        d.add(Line(x1, y, x2-8, y, strokeColor=color, strokeWidth=2))
        d.add(Polygon([x2-8, y+4, x2-8, y-4, x2, y],
                      fillColor=color, strokeColor=color, strokeWidth=0))
        if label:
            mid = (x1+x2)/2
            d.add(String(mid, y+4, label, fontName="Helvetica", fontSize=7,
                         fillColor=color, textAnchor="middle"))
    
    def label_line(x, y, text, color=GRAY):
        d.add(String(x, y, text, fontName="Helvetica", fontSize=7.5,
                     fillColor=color, textAnchor="middle"))
    
    bw = 160; bh = 28
    
    # Row 1: Clinical Suspicion
    y1 = H - 35
    box(cx-bw/2, y1, bw, bh, "CLINICAL SUSPICION OF CVA\n(BE-FAST Signs)", DARK_BLUE, DARK_BLUE, radius=8)
    
    arrow_down(cx, y1, y1-30)
    
    # Row 2: NCCT Brain
    y2 = y1 - 60
    box(cx-bw/2, y2, bw, bh, "NCCT Brain\n(Non-Contrast CT)", MED_BLUE, MED_BLUE)
    
    # Branch: Hemorrhage vs No Hemorrhage
    arrow_down(cx, y2, y2-30)
    
    y3 = y2 - 56
    # No Hemorrhage
    bw2 = 130
    box(cx-bw2/2, y3, bw2, bh, "No Hemorrhage\nFound", GREEN, GREEN)
    
    # Also add hemorrhagic branch
    hx = cx + 150
    box(hx - 70, y3, 140, bh, "Hemorrhage\nPresent", RED, RED)
    arrow_right(cx+bw/2, hx-70, y2+bh/2, RED, "If hemorrhage")
    d.add(String(hx, y3-14, "→ Neurosurgery consult", fontName="Helvetica",
                 fontSize=7.5, fillColor=RED, textAnchor="middle"))
    d.add(String(hx, y3-26, "→ Reverse anticoagulation", fontName="Helvetica",
                 fontSize=7.5, fillColor=RED, textAnchor="middle"))
    d.add(String(hx, y3-38, "→ BP control", fontName="Helvetica",
                 fontSize=7.5, fillColor=RED, textAnchor="middle"))
    
    arrow_down(cx, y3, y3-30)
    
    # Row 4: ONSET Time
    y4 = y3 - 56
    box(cx - bw/2, y4, bw, bh, "Determine ONSET\n(Last Seen Normal)", ORANGE, ORANGE)
    
    arrow_down(cx, y4, y4-28)
    
    # Three branches: <4.5h, 4.5-24h, >24h
    y5 = y4 - 60
    bw3 = 110; bh3 = 30
    
    x_left   = cx - 220
    x_mid    = cx
    x_right  = cx + 220
    
    # branch lines from center
    branch_y = y4 - 28
    d.add(Line(cx, branch_y, x_left + bw3/2, branch_y, strokeColor=MED_BLUE, strokeWidth=1.5))
    d.add(Line(cx, branch_y, x_right + bw3/2, branch_y, strokeColor=GRAY, strokeWidth=1.5))
    # arrows down to boxes
    arrow_down(x_left + bw3/2, branch_y, y5+bh3, GREEN)
    arrow_down(x_mid - bw3/2 + bw3/2, branch_y, y5+bh3, ORANGE)
    arrow_down(x_right + bw3/2, branch_y, y5+bh3, GRAY)
    
    box(x_left, y5, bw3, bh3, "< 4.5 Hours", GREEN, GREEN, font_size=10)
    box(x_mid-bw3/2, y5, bw3, bh3, "4.5 – 24 Hours", ORANGE, ORANGE, font_size=9)
    box(x_right, y5, bw3, bh3, "> 24 Hours", GRAY, GRAY, font_size=10)
    
    # Tier 1 actions
    y6 = y5 - 50
    bh4 = 36
    box(x_left, y6, bw3, bh4, "IV rtPA\n(0.9 mg/kg)\nAlteplase > Tenectaplase", GREEN, GREEN, font_size=8)
    arrow_down(x_left + bw3/2, y5, y6+bh4, GREEN)
    
    box(x_mid-bw3/2, y6, bw3, bh4, "DWI MRI\nIschemic Penumbra\nvs Infarct Core", ORANGE, ORANGE, font_size=8)
    arrow_down(x_mid, y5, y6+bh4, ORANGE)
    
    box(x_right, y6, bw3, bh4, "Aspirin\n(Antiplatelet\nTherapy)", GRAY, GRAY, font_size=8)
    arrow_down(x_right + bw3/2, y5, y6+bh4, GRAY)
    
    # No Response → Cerebral Angiography
    y7 = y6 - 52
    bh5 = 28
    cx2 = x_left + bw3/2
    d.add(String(cx2, y6 - 10, "No Response?", fontName="Helvetica-Bold",
                 fontSize=7.5, fillColor=RED, textAnchor="middle"))
    arrow_down(cx2, y6, y7+bh5, RED)
    box(cx2-70, y7, 140, bh5, "Cerebral Angiography", MED_BLUE, DARK_BLUE, font_size=9)
    
    # LVO branch
    y8 = y7 - 48
    bh6 = 28
    lvo_x = cx2 - 90
    mec_x = cx2 + 20
    
    # arrow splits
    arrow_down(cx2, y7, y8+bh6, MED_BLUE)
    
    box(lvo_x, y8, 100, bh6, "LVO Found\n(Large Vessel Occ.)", RED, RED, font_size=8)
    box(mec_x, y8, 120, bh6, "Mechanical\nThrombectomy /\nIntra-arterial rtPA", PURPLE, PURPLE, font_size=7.5)
    
    arrow_right(lvo_x+100, mec_x, y8+bh6/2, PURPLE)
    
    # 4.5-24h additional note
    d.add(String(x_mid, y6-14, "If deficit > infarct size:", fontName="Helvetica",
                 fontSize=7, fillColor=ORANGE, textAnchor="middle"))
    d.add(String(x_mid, y6-26, "→ Give rtPA / Thrombectomy", fontName="Helvetica",
                 fontSize=7, fillColor=ORANGE, textAnchor="middle"))
    
    return d


def make_ci_rtpa_table():
    """Contraindications of rtPA table."""
    headers = ["#", "Contraindication", "Reason"]
    rows = [
        ["1", "BP > 185/100 mmHg", "Risk of hemorrhagic transformation increases"],
        ["2", "Bleeding Diathesis", "Any clotting disorder prevents safe thrombolysis"],
        ["3", "Past H/o Hemorrhagic Stroke", "Prior brain bleed = very high re-bleed risk"],
        ["4", "Rapidly Improving Symptoms (TIA)", "Symptoms resolving — benefit may not outweigh risk"],
        ["5", "Recent major surgery (< 14 days)", "Active wound — systemic lysis can cause bleeding"],
        ["6", "Recent GI/GU bleed (< 21 days)", "Active internal bleeding risk"],
        ["7", "Head trauma (< 3 months)", "Traumatized vessels at high bleed risk"],
        ["8", "Platelet count < 100,000", "Inadequate clotting reserve"],
        ["9", "INR > 1.7 or on warfarin", "Anticoagulated — cannot safely lyse"],
    ]
    col_widths = [1.2*cm, 7.5*cm, 7.5*cm]
    all_rows = [headers] + rows
    
    style = [
        ("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
        ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
        ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE",   (0,0), (-1,0), 10),
        ("FONTSIZE",   (0,0), (-1,-1), 9),
        ("ALIGN",      (0,0), (0,-1), "CENTER"),
        ("VALIGN",     (0,0), (-1,-1), "MIDDLE"),
        ("GRID",       (0,0), (-1,-1), 0.5, colors.HexColor("#BDC3C7")),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_GRAY]),
        ("TOPPADDING",  (0,0), (-1,-1), 5),
        ("BOTTOMPADDING",(0,0), (-1,-1), 5),
        ("LEFTPADDING", (0,0), (-1,-1), 6),
        ("RIGHTPADDING",(0,0), (-1,-1), 6),
        ("BACKGROUND", (0,1), (0,-1), LIGHT_RED),
        ("TEXTCOLOR",  (0,1), (0,-1), RED),
        ("FONTNAME",   (0,1), (0,-1), "Helvetica-Bold"),
    ]
    
    data = [[Paragraph(str(c), make_style(f"tc{i}{j}", fontSize=9,
                        textColor=WHITE if i==0 else BLACK,
                        fontName="Helvetica-Bold" if i==0 else "Helvetica"))
             for j, c in enumerate(row)] for i, row in enumerate(all_rows)]
    
    t = Table(data, colWidths=col_widths, repeatRows=1)
    t.setStyle(TableStyle(style))
    return t


def make_drug_table():
    """Drug therapy table."""
    headers = ["Drug", "Class", "Dose / Route", "When Used"]
    rows = [
        ["Alteplase (rtPA)", "Thrombolytic", "0.9 mg/kg IV\n(max 90 mg)\n10% bolus, rest over 60 min", "Ischemic stroke < 4.5 hrs\nFirst-line thrombolytic"],
        ["Tenectaplase", "Thrombolytic", "0.25 mg/kg IV\n(single bolus)", "Alternative to alteplase\n< 4.5 hrs (easier dosing)"],
        ["Aspirin", "Antiplatelet", "162–325 mg\nPO/PR loading", "> 24 hrs from onset\nNot suitable for thrombolysis\nPrimary prevention"],
        ["Aspirin + Clopidogrel", "Dual Antiplatelet\n(DAPT)", "Aspirin 75–325 mg +\nClopidogrel 75 mg daily", "High-risk TIA\nMinor stroke (NIHSS ≤3)\n21-day dual therapy"],
        ["Heparin → Warfarin", "Anticoagulant", "UFH drip → INR target 2–3", "AF with cardioembolic stroke\nProsthetic heart valves"],
        ["NOACs (e.g., Apixaban)", "Anticoagulant", "As per indication", "AF secondary prevention\n(preferred over warfarin)"],
        ["Labetalol / Nicardipine", "Antihypertensive", "IV titration", "BP management pre/post rtPA\nTarget <185/110 for rtPA"],
    ]
    col_widths = [3.5*cm, 3.0*cm, 4.0*cm, 5.8*cm]
    all_rows = [headers] + rows
    
    data = [[Paragraph(str(c), make_style(f"dc{i}{j}", fontSize=8.5,
                        textColor=WHITE if i==0 else DARK_BLUE,
                        fontName="Helvetica-Bold" if i==0 else "Helvetica",
                        leading=12))
             for j, c in enumerate(row)] for i, row in enumerate(all_rows)]
    
    t = Table(data, colWidths=col_widths, repeatRows=1)
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
        ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
        ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
        ("VALIGN",     (0,0), (-1,-1), "TOP"),
        ("GRID",       (0,0), (-1,-1), 0.5, colors.HexColor("#BDC3C7")),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_BLUE]),
        ("TOPPADDING",  (0,0), (-1,-1), 5),
        ("BOTTOMPADDING",(0,0), (-1,-1), 5),
        ("LEFTPADDING", (0,0), (-1,-1), 6),
        ("RIGHTPADDING",(0,0), (-1,-1), 6),
    ]))
    return t


# ── PAGE BACKGROUND ───────────────────────────────────────────────────────────
def on_first_page(canvas_obj, doc):
    canvas_obj.saveState()
    # Cover gradient (simulate with two rects)
    canvas_obj.setFillColor(DARK_BLUE)
    canvas_obj.rect(0, PAGE_H*0.45, PAGE_W, PAGE_H*0.55, fill=1, stroke=0)
    canvas_obj.setFillColor(MED_BLUE)
    canvas_obj.rect(0, 0, PAGE_W, PAGE_H*0.45, fill=1, stroke=0)
    # Decorative circle
    canvas_obj.setFillColor(colors.HexColor("#FFFFFF10"))
    canvas_obj.circle(PAGE_W*0.85, PAGE_H*0.75, 120, fill=1, stroke=0)
    canvas_obj.circle(PAGE_W*0.1, PAGE_H*0.2, 80, fill=1, stroke=0)
    canvas_obj.restoreState()


def on_later_pages(canvas_obj, doc):
    canvas_obj.saveState()
    # Header bar
    canvas_obj.setFillColor(DARK_BLUE)
    canvas_obj.rect(0, PAGE_H - 1.2*cm, PAGE_W, 1.2*cm, fill=1, stroke=0)
    canvas_obj.setFillColor(WHITE)
    canvas_obj.setFont("Helvetica", 8)
    canvas_obj.drawString(MARGIN, PAGE_H - 0.8*cm, "CVA Management Guide")
    canvas_obj.drawRightString(PAGE_W - MARGIN, PAGE_H - 0.8*cm, f"Page {doc.page}")
    # Footer
    canvas_obj.setFillColor(LIGHT_GRAY)
    canvas_obj.rect(0, 0, PAGE_W, 1.0*cm, fill=1, stroke=0)
    canvas_obj.setFillColor(GRAY)
    canvas_obj.setFont("Helvetica-Oblique", 7.5)
    canvas_obj.drawCentredString(PAGE_W/2, 0.35*cm,
        "For educational purposes only — always follow current institutional protocols and guidelines")
    canvas_obj.restoreState()


# ── BUILD PDF ─────────────────────────────────────────────────────────────────
OUT = "/tmp/workspace/cva-pdf/CVA_Management_Guide.pdf"
doc = SimpleDocTemplate(
    OUT, pagesize=A4,
    leftMargin=MARGIN, rightMargin=MARGIN,
    topMargin=1.8*cm, bottomMargin=1.5*cm,
    title="CVA Management Guide",
    author="Orris Medical Education",
)

story = []

# ─────────── COVER PAGE ───────────────────────────────────────────────────────
story.append(Spacer(1, 3.5*cm))
story.append(Paragraph("CEREBROVASCULAR ACCIDENT", Title_S))
story.append(Paragraph("CVA / STROKE", make_style("cov2", fontSize=22, textColor=YELLOW,
             alignment=TA_CENTER, fontName="Helvetica-Bold", spaceAfter=10)))
story.append(Paragraph("Complete Management Guide", Sub_S))
story.append(Spacer(1, 0.5*cm))
story.append(HRFlowable(width="60%", thickness=2, color=YELLOW, spaceAfter=12, spaceBefore=0, hAlign="CENTER"))
story.append(Paragraph("From Clinical Recognition to Reperfusion Therapy", 
             make_style("cov3", fontSize=12, textColor=LIGHT_BLUE, alignment=TA_CENTER, spaceAfter=8)))
story.append(Spacer(1, 1.5*cm))

# BE-FAST visual on cover
story.append(Paragraph("RECOGNIZE A STROKE: BE-FAST", 
             make_style("bf_hdr", fontSize=14, textColor=WHITE, alignment=TA_CENTER,
                        fontName="Helvetica-Bold", spaceAfter=8)))
story.append(make_befast_chart())
story.append(Spacer(1, 0.4*cm))
story.append(Paragraph("Balance | Eye (Blurring) | Facial Asymmetry | Arm Weakness | Speech Deficit | Time",
             make_style("bf_sub", fontSize=9, textColor=LIGHT_BLUE, alignment=TA_CENTER, spaceAfter=4)))

story.append(Spacer(1, 2.0*cm))
story.append(Paragraph("Time is Brain — Every minute 1.9 million neurons die during a stroke",
             make_style("quote", fontSize=11, textColor=YELLOW, alignment=TA_CENTER,
                        fontName="Helvetica-BoldOblique", spaceAfter=6)))
story.append(PageBreak())


# ─────────── PAGE 2: OVERVIEW ─────────────────────────────────────────────────
story.append(section_header("WHAT IS A STROKE (CVA)?"))
story.append(Spacer(1, 0.3*cm))

story.append(Paragraph(
    "A <b>Cerebrovascular Accident (CVA)</b>, commonly called a <b>stroke</b>, occurs when blood supply "
    "to a part of the brain is suddenly interrupted. Without oxygen and glucose, brain cells begin dying "
    "within minutes. Stroke is a <b>medical emergency</b> — the faster treatment is given, the better the outcome.",
    Body_S))
story.append(Spacer(1, 0.2*cm))

# Two-column: types
type_data = [
    [
        Paragraph("<b>🔴 Ischemic Stroke (85%)</b>", make_style("t1", fontSize=11, textColor=RED, fontName="Helvetica-Bold")),
        Paragraph("<b>🩸 Hemorrhagic Stroke (15%)</b>", make_style("t2", fontSize=11, textColor=MED_BLUE, fontName="Helvetica-Bold")),
    ],
    [
        Paragraph("Caused by a <b>clot or thrombosis</b> blocking an artery. "
                  "The affected area (penumbra) is initially salvageable with rapid reperfusion. "
                  "Subtypes: thrombotic, embolic (from heart — AF, valve disease), lacunar.",
                  make_style("t1b", fontSize=9, leading=13)),
        Paragraph("Caused by <b>rupture of a blood vessel</b> causing bleeding into the brain "
                  "(intracerebral) or around it (subarachnoid). Risk factors include uncontrolled "
                  "hypertension, AVM, aneurysm.",
                  make_style("t2b", fontSize=9, leading=13)),
    ]
]
tt = Table(type_data, colWidths=[(PAGE_W-2*MARGIN-0.5*cm)/2]*2, hAlign="LEFT")
tt.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (0,-1), LIGHT_RED),
    ("BACKGROUND", (1,0), (1,-1), LIGHT_BLUE),
    ("BOX", (0,0), (0,-1), 1.5, RED),
    ("BOX", (1,0), (1,-1), 1.5, MED_BLUE),
    ("TOPPADDING", (0,0), (-1,-1), 8),
    ("BOTTOMPADDING", (0,0), (-1,-1), 8),
    ("LEFTPADDING", (0,0), (-1,-1), 10),
    ("RIGHTPADDING", (0,0), (-1,-1), 10),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("COLPADDING", (0,0), (-1,-1), 5),
]))
story.append(tt)
story.append(Spacer(1, 0.3*cm))

story.append(Paragraph("TIA (Transient Ischemic Attack)", H2_S))
story.append(Paragraph(
    "A TIA is a 'mini-stroke' — symptoms appear suddenly but <b>resolve completely within 24 hours</b> "
    "(usually within minutes). It is a major warning sign: <b>10-15% of TIA patients have a full stroke "
    "within 3 months</b>, most commonly within 48 hours. TIA requires urgent evaluation and secondary "
    "prevention — it is NOT a reason to withhold treatment.",
    Body_S))
story.append(Spacer(1, 0.3*cm))

# Risk factors
story.append(Paragraph("Key Risk Factors", H3_S))
rf_data = [
    ["Modifiable (Can be treated)", "Non-Modifiable"],
    ["• Hypertension (single biggest risk factor)\n• Atrial Fibrillation (AF)\n• Diabetes Mellitus\n"
     "• Hyperlipidemia\n• Smoking & alcohol\n• Obesity & physical inactivity\n• Carotid artery stenosis",
     "• Age > 55 years\n• Male sex\n• Family history of stroke\n• Prior stroke / TIA\n• Race (higher in South Asians, Africans)\n• Sickle cell disease"]
]
rf_table = Table(
    [[Paragraph(str(c), make_style(f"rf{i}{j}", fontSize=9, leading=13,
                                   textColor=WHITE if i==0 else BLACK,
                                   fontName="Helvetica-Bold" if i==0 else "Helvetica"))
      for j,c in enumerate(r)] for i,r in enumerate(rf_data)],
    colWidths=[(PAGE_W-2*MARGIN-0.4*cm)/2]*2
)
rf_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (0,0), GREEN),
    ("BACKGROUND", (1,0), (1,0), GRAY),
    ("BACKGROUND", (0,1), (0,1), LIGHT_GREEN),
    ("BACKGROUND", (1,1), (1,1), LIGHT_GRAY),
    ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#BDC3C7")),
    ("TOPPADDING", (0,0), (-1,-1), 8),
    ("BOTTOMPADDING", (0,0), (-1,-1), 8),
    ("LEFTPADDING", (0,0), (-1,-1), 10),
    ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(rf_table)
story.append(PageBreak())


# ─────────── PAGE 3: RECOGNITION & INITIAL ASSESSMENT ────────────────────────
story.append(section_header("INITIAL RECOGNITION & ASSESSMENT"))
story.append(Spacer(1, 0.3*cm))

story.append(Paragraph(
    "On clinical suspicion of stroke, use the <b>BE-FAST mnemonic</b> for rapid bedside recognition. "
    "Any of these signs mandates immediate activation of the stroke protocol and emergency imaging.",
    Body_S))
story.append(Spacer(1, 0.2*cm))

# BE-FAST detailed
befast_rows = [
    ["B", "Balance", "Sudden loss of balance or coordination; unsteady gait", "Ask to walk in a straight line"],
    ["E", "Eye", "Sudden blurred vision, double vision, or loss of vision in one/both eyes", "Cover each eye; check visual fields"],
    ["F", "Face", "Facial asymmetry — one side drooping; unequal smile", "Ask to smile / show teeth"],
    ["A", "Arm", "Arm weakness — one arm drifts down when both arms raised", "Pronator drift test (30 seconds)"],
    ["S", "Speech", "Slurred speech, word-finding difficulty, or nonsensical speech", "Ask to repeat 'The sky is blue'"],
    ["T", "Time", "Note the EXACT time of symptom onset or last seen normal", "Critical for thrombolysis eligibility"],
]
bf_headers = ["Letter", "Sign", "What to Look For", "Quick Test"]
bf_data = [bf_headers] + befast_rows
bf_table = Table(
    [[Paragraph(str(c), make_style(f"bf{i}{j}", fontSize=9, leading=12,
                                   textColor=WHITE if i==0 else BLACK,
                                   fontName="Helvetica-Bold" if (i==0 or j==0) else "Helvetica"))
      for j,c in enumerate(r)] for i,r in enumerate(bf_data)],
    colWidths=[1.5*cm, 2.5*cm, 7.0*cm, 5.2*cm], repeatRows=1
)
bf_colors_list = [RED, ORANGE, colors.HexColor("#F39C12"), GREEN, MED_BLUE, PURPLE]
bf_ts = [
    ("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
    ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#BDC3C7")),
    ("TOPPADDING", (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING", (0,0), (-1,-1), 6),
    ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_GRAY]),
]
for idx, col in enumerate(bf_colors_list):
    bf_ts.append(("BACKGROUND", (0, idx+1), (0, idx+1), col))
    bf_ts.append(("TEXTCOLOR", (0, idx+1), (0, idx+1), WHITE))
bf_table.setStyle(TableStyle(bf_ts))
story.append(bf_table)
story.append(Spacer(1, 0.3*cm))

# NIHSS box
story.append(Paragraph("NIHSS - Stroke Severity Score", H3_S))
nihss_data = [
    ["NIHSS Score", "Severity", "Clinical Meaning"],
    ["0",          "No stroke", "Normal examination"],
    ["1–4",        "Minor stroke", "Usually can be managed medically"],
    ["5–15",       "Moderate stroke", "Core target for reperfusion therapy"],
    ["16–20",      "Moderate-severe", "High disability — aggressive management"],
    ["21–42",      "Severe stroke", "High mortality; aggressive intervention needed"],
]
nihss_table = Table(
    [[Paragraph(str(c), make_style(f"nih{i}{j}", fontSize=9,
                                   textColor=WHITE if i==0 else BLACK,
                                   fontName="Helvetica-Bold" if i==0 else "Helvetica"))
      for j,c in enumerate(r)] for i,r in enumerate(nihss_data)],
    colWidths=[3*cm, 4*cm, 9.2*cm], repeatRows=1
)
nihss_bg = [GREEN, GREEN, ORANGE, RED, RED]
nihss_ts = [
    ("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
    ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#BDC3C7")),
    ("TOPPADDING", (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING", (0,0), (-1,-1), 8),
    ("RIGHTPADDING", (0,0), (-1,-1), 8),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_GRAY]),
]
for idx, col in enumerate(nihss_bg):
    nihss_ts.append(("BACKGROUND", (0, idx+1), (0, idx+1), col))
    nihss_ts.append(("TEXTCOLOR", (0, idx+1), (0, idx+1), WHITE))
nihss_table.setStyle(TableStyle(nihss_ts))
story.append(nihss_table)
story.append(PageBreak())


# ─────────── PAGE 4: MAIN MANAGEMENT FLOWCHART ────────────────────────────────
story.append(section_header("CVA MANAGEMENT FLOWCHART", bg=GREEN))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph(
    "The following flowchart shows the complete decision pathway from clinical suspicion of CVA through "
    "emergency imaging, thrombolysis eligibility, and interventional options. Time at each step is critical.",
    Body_S))
story.append(Spacer(1, 0.2*cm))
story.append(make_main_flowchart())
story.append(PageBreak())


# ─────────── PAGE 5: IMAGING ──────────────────────────────────────────────────
story.append(section_header("EMERGENCY IMAGING IN STROKE", bg=MED_BLUE))
story.append(Spacer(1, 0.3*cm))

story.append(Paragraph("Step 1: NCCT Brain (Non-Contrast CT)", H2_S))
story.append(Paragraph(
    "The <b>first and most important imaging step</b>. Done immediately on arrival. The SOLE initial purpose "
    "is to <b>rule out hemorrhage</b>. If no blood is seen, the stroke is presumed ischemic and thrombolysis "
    "can be considered. NCCT is fast, widely available, and does not require contrast.",
    Body_S))

# NCCT image
if "ncct_stroke" in img_paths:
    try:
        img = RLImage(img_paths["ncct_stroke"], width=14*cm, height=7*cm)
        img.hAlign = "CENTER"
        story.append(img)
        story.append(Paragraph(
            "NCCT Brain (left) ruling out hemorrhage vs CT Angiogram (right) showing M2 MCA occlusion (red circle). "
            "NCCT is used to exclude hemorrhage; CTA identifies large vessel occlusion (LVO).",
            Caption_S))
    except: pass
story.append(Spacer(1, 0.3*cm))

story.append(Paragraph("Step 2: Diffusion-Weighted MRI (DWI)", H2_S))
story.append(Paragraph(
    "<b>DWI MRI is the gold standard</b> for detecting acute ischemic stroke. It shows restricted diffusion "
    "(bright on DWI, dark on ADC) within minutes of stroke onset. Key use case: the 4.5–24 hour window — "
    "DWI identifies the <b>ischemic penumbra</b> (tissue at risk but not yet dead) vs the <b>infarct core</b> "
    "(already infarcted). If deficit size is larger than the infarct core (mismatch), reperfusion therapy is still beneficial.",
    Body_S))

if "mri_stroke" in img_paths:
    try:
        img = RLImage(img_paths["mri_stroke"], width=14*cm, height=6.5*cm)
        img.hAlign = "CENTER"
        story.append(img)
        story.append(Paragraph(
            "Left: NCCT showing no visible lesion (CT-occult stroke). Middle: DWI showing bright hyperintensity "
            "in right internal capsule (acute ischemia). Right: ADC map confirming restricted diffusion (dark = cytotoxic edema).",
            Caption_S))
    except: pass
story.append(Spacer(1, 0.3*cm))

# Imaging comparison table
story.append(Paragraph("Imaging Comparison", H3_S))
img_compare = [
    ["Modality", "Purpose", "Best For", "Time to Acquire"],
    ["NCCT Brain", "Rule out hemorrhage", "ALL acute strokes (first line)", "~5 minutes"],
    ["CT Angiography (CTA)", "Identify vessel occlusion", "Detecting LVO for thrombectomy", "~10 minutes"],
    ["MRI DWI", "Confirm ischemia & penumbra", "4.5–24 hr window; minor strokes", "~20–30 minutes"],
    ["MRI PWI/DWI Mismatch", "Penumbra assessment", "Extended window reperfusion selection", "~30–45 minutes"],
    ["Cerebral Angiography (DSA)", "Definitive vascular roadmap", "Pre-thrombectomy in LVO", "~30–60 minutes"],
]
img_table = Table(
    [[Paragraph(str(c), make_style(f"im{i}{j}", fontSize=9, leading=12,
                                   textColor=WHITE if i==0 else DARK_BLUE,
                                   fontName="Helvetica-Bold" if i==0 else "Helvetica"))
      for j,c in enumerate(r)] for i,r in enumerate(img_compare)],
    colWidths=[3.5*cm, 4*cm, 4.5*cm, 4.2*cm], repeatRows=1
)
img_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
    ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#BDC3C7")),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_BLUE]),
    ("TOPPADDING", (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING", (0,0), (-1,-1), 8),
    ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(img_table)
story.append(PageBreak())


# ─────────── PAGE 6: THROMBOLYSIS ─────────────────────────────────────────────
story.append(section_header("THROMBOLYSIS: rtPA (Alteplase / Tenectaplase)", bg=RED))
story.append(Spacer(1, 0.3*cm))

story.append(Paragraph(
    "<b>IV rtPA (recombinant tissue plasminogen activator)</b> is the primary reperfusion treatment for "
    "acute ischemic stroke within the treatment window. It works by converting plasminogen to plasmin, "
    "which then dissolves the clot (fibrinolysis). It is the <b>only FDA-approved drug for acute ischemic stroke</b>.",
    Body_S))
story.append(Spacer(1, 0.2*cm))

# Dosing
story.append(info_box([
    "• <b>Alteplase (first choice):</b> 0.9 mg/kg IV (maximum 90 mg). Give 10% as IV bolus over 1 minute, then remaining 90% as IV infusion over 60 minutes.",
    "• <b>Tenectaplase (alternative):</b> 0.25 mg/kg IV as a single bolus (max 25 mg). Easier — one-time dose, non-inferior in many trials.",
    "• Start within 4.5 hours of last seen normal (onset).",
    "• Do NOT give antiplatelet or anticoagulant for 24 hours after rtPA.",
], title="rtPA Dosing Protocol", bg=LIGHT_RED, border=RED, title_bg=RED))
story.append(Spacer(1, 0.3*cm))

story.append(Paragraph("Contraindications to rtPA", H2_S))
story.append(Paragraph(
    "Before giving rtPA, carefully screen for the following contraindications. Missing any of these "
    "can lead to life-threatening bleeding, including fatal intracerebral hemorrhage.",
    Body_S))
story.append(Spacer(1, 0.2*cm))
story.append(make_ci_rtpa_table())
story.append(Spacer(1, 0.3*cm))

# Monitoring after rtPA
story.append(Paragraph("Monitoring After rtPA", H3_S))
story.append(info_box([
    "• ICU/stroke unit admission — close neurological monitoring for 24 hours",
    "• BP target: < 180/105 mmHg for 24 hours post-thrombolysis",
    "• Repeat NCCT at 24 hours to check for hemorrhagic transformation",
    "• No NG tubes, arterial lines, or urinary catheters for first 30 minutes if possible",
    "• If deterioration: STOP infusion, get STAT NCCT, consider reversal (cryoprecipitate, FFP)",
    "• NPO until formal swallowing assessment completed",
], bg=LIGHT_YELLOW, border=YELLOW, title="Post-rtPA Care", title_bg=ORANGE))
story.append(PageBreak())


# ─────────── PAGE 7: THROMBECTOMY & INTERVENTIONAL ────────────────────────────
story.append(section_header("MECHANICAL THROMBECTOMY & INTERVENTIONAL THERAPY", bg=PURPLE))
story.append(Spacer(1, 0.3*cm))

story.append(Paragraph(
    "<b>Mechanical thrombectomy</b> is a game-changing procedure for <b>Large Vessel Occlusion (LVO)</b>. "
    "A catheter is advanced into the blocked cerebral artery (typically ICA, MCA, basilar) and a "
    "<b>stent retriever or aspiration device</b> physically removes the clot. It has dramatically improved "
    "outcomes in LVO stroke.",
    Body_S))
story.append(Spacer(1, 0.2*cm))

# Thrombectomy image
if "thrombectomy" in img_paths:
    try:
        img = RLImage(img_paths["thrombectomy"], width=14*cm, height=6.5*cm)
        img.hAlign = "CENTER"
        story.append(img)
        story.append(Paragraph(
            "Left: DSA showing acute MCA M1 occlusion (arrow). Middle: Stent retriever with retrieved red thrombus. "
            "Right: Post-thrombectomy DSA showing TICI 3 complete recanalization of the MCA territory.",
            Caption_S))
    except: pass
story.append(Spacer(1, 0.3*cm))

# Thrombectomy criteria
story.append(info_box([
    "• <b>LVO confirmed</b> on CTA (ICA, M1/M2 MCA, basilar artery, ACA)",
    "• <b>Time window:</b> Up to 24 hours from last seen normal (with appropriate patient selection)",
    "• <b>NIHSS ≥ 6</b> (significant neurological deficit)",
    "• <b>Good pre-morbid function</b> (mRS 0–2 before stroke)",
    "• <b>Penumbra > core ratio</b> on advanced imaging (RAPID software, DEFUSE 3 / DAWN trial criteria)",
    "• NOT contraindicated by hemorrhage or large established infarct (> 1/3 MCA territory)",
], title="Thrombectomy Eligibility Criteria", bg=LIGHT_PURPLE, border=PURPLE, title_bg=PURPLE))
story.append(Spacer(1, 0.3*cm))

story.append(Paragraph("Vessels Involved in Stroke", H2_S))
vessel_data = [
    ["Vessel", "Territory Supplied", "Typical Syndrome if Occluded"],
    ["ICA (Internal Carotid)", "Ipsilateral hemisphere", "Contralateral hemiplegia, aphasia (if dominant)"],
    ["MCA (Middle Cerebral)", "Lateral cortex, basal ganglia", "Contralateral face+arm weakness > leg, aphasia (dominant)"],
    ["ACA (Anterior Cerebral)", "Medial frontal, parietal lobe", "Contralateral leg weakness > arm"],
    ["PCA (Posterior Cerebral)", "Occipital, thalamus", "Contralateral hemianopia, thalamic syndrome"],
    ["Basilar Artery", "Brainstem, cerebellum", "Locked-in syndrome, coma, death — EMERGENCY"],
    ["PICA", "Lateral medulla, cerebellum", "Wallenberg syndrome — vertigo, dysarthria, Horner's"],
]
v_table = Table(
    [[Paragraph(str(c), make_style(f"vs{i}{j}", fontSize=9, leading=12,
                                   textColor=WHITE if i==0 else DARK_BLUE,
                                   fontName="Helvetica-Bold" if i==0 else "Helvetica"))
      for j,c in enumerate(r)] for i,r in enumerate(vessel_data)],
    colWidths=[4*cm, 4.5*cm, 7.7*cm], repeatRows=1
)
v_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
    ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#BDC3C7")),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_PURPLE]),
    ("TOPPADDING", (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING", (0,0), (-1,-1), 8),
    ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(v_table)
story.append(PageBreak())


# ─────────── PAGE 8: ANTIPLATELET / ANTICOAGULATION ─────────────────────────
story.append(section_header("DRUG THERAPY: ANTIPLATELET, ANTICOAGULATION & MORE", bg=ORANGE))
story.append(Spacer(1, 0.3*cm))
story.append(make_drug_table())
story.append(Spacer(1, 0.3*cm))

story.append(Paragraph("When NOT to Give rtPA — Use Antiplatelet Instead", H2_S))
ap_rows = [
    ["Scenario", "Treatment of Choice"],
    ["> 24 hours from onset", "Aspirin 160-325 mg loading, then 75-100 mg daily"],
    ["Rapidly improving / resolving (TIA)", "Aspirin + Clopidogrel (DAPT) for 21 days — HIGH-RISK TIA"],
    ["On anticoagulants already", "Continue anticoagulation; do NOT add thrombolytics"],
    ["Mild stroke (NIHSS < 5)", "DAPT (Aspirin + Clopidogrel) within 24 hrs, for 21 days"],
    ["Cardioembolic (AF) stroke", "Anticoagulate: Heparin bridge → NOAC (e.g., Apixaban, Rivaroxaban)"],
    ["Prosthetic valve / high-risk AF", "Heparin → Warfarin (target INR 2.5–3.5 for mechanical valve)"],
]
ap_table = Table(
    [[Paragraph(str(c), make_style(f"ap{i}{j}", fontSize=9, leading=12,
                                   textColor=WHITE if i==0 else DARK_BLUE,
                                   fontName="Helvetica-Bold" if i==0 else "Helvetica"))
      for j,c in enumerate(r)] for i,r in enumerate(ap_rows)],
    colWidths=[6*cm, 10.2*cm], repeatRows=1
)
ap_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), ORANGE),
    ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#BDC3C7")),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_ORANGE]),
    ("TOPPADDING", (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING", (0,0), (-1,-1), 8),
    ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(ap_table)
story.append(Spacer(1, 0.3*cm))

# BP management
story.append(Paragraph("Blood Pressure Management in Acute Stroke", H2_S))
bp_rows = [
    ["Situation", "BP Target", "Agent"],
    ["Before rtPA (to qualify)", "< 185/110 mmHg", "Labetalol 10–20 mg IV or Nicardipine infusion"],
    ["During/after rtPA (24 hrs)", "< 180/105 mmHg", "Labetalol, Nicardipine"],
    ["Ischemic stroke without rtPA", "< 220/120 mmHg\n(permissive hypertension)", "Treat only if >220/120 or symptomatic"],
    ["Hemorrhagic stroke", "< 140/90 mmHg (aggressive)", "Nicardipine or Labetalol infusion"],
    ["BP too LOW (hypotension)", "Maintain adequate cerebral perfusion pressure", "IV fluids, vasopressors if needed"],
]
bp_table = Table(
    [[Paragraph(str(c), make_style(f"bp{i}{j}", fontSize=9, leading=12,
                                   textColor=WHITE if i==0 else DARK_BLUE,
                                   fontName="Helvetica-Bold" if i==0 else "Helvetica"))
      for j,c in enumerate(r)] for i,r in enumerate(bp_rows)],
    colWidths=[5.5*cm, 4.5*cm, 6.2*cm], repeatRows=1
)
bp_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), RED),
    ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#BDC3C7")),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_RED]),
    ("TOPPADDING", (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING", (0,0), (-1,-1), 8),
    ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(bp_table)
story.append(PageBreak())


# ─────────── PAGE 9: GENERAL CARE & SECONDARY PREVENTION ────────────────────
story.append(section_header("GENERAL CARE IN ACUTE STROKE", bg=GREEN))
story.append(Spacer(1, 0.3*cm))

care_data = [
    ["System", "Key Points"],
    ["Airway & Breathing", "Maintain SpO2 > 94%. Give O2 only if hypoxic. Intubate if GCS < 8 or airway not protected."],
    ["Circulation", "IV access × 2. Monitor cardiac rhythm (24–48 hrs) — detect AF. Treat hypotension, avoid hypotension."],
    ["Glucose", "Target glucose 140–180 mg/dL. Treat hypoglycaemia immediately (can mimic stroke). Avoid glucose-containing fluids."],
    ["Temperature", "Treat fever aggressively (paracetamol). Each 1°C increase worsens brain injury."],
    ["Swallowing", "Nil by mouth (NPO) until formal swallow assessment (bedside / videofluoroscopy). NGT if unsafe swallow."],
    ["Positioning", "Head elevated 30–45° (reduces ICP). Avoid neck vein compression. DVT prophylaxis (compression stockings, LMWH after 24–48 hrs)."],
    ["Bladder / Bowel", "Avoid urinary catheterization if possible. Constipation increases ICP — stool softeners."],
    ["Pressure Care", "Reposition every 2 hours. Pressure ulcer prevention from day 1."],
    ["Rehabilitation", "Start early physiotherapy, speech, OT within 24–48 hrs if stable. Neuroplasticity is maximal early."],
]
care_table = Table(
    [[Paragraph(str(c), make_style(f"cr{i}{j}", fontSize=9, leading=12,
                                   textColor=WHITE if i==0 else DARK_BLUE,
                                   fontName="Helvetica-Bold" if (i==0 or j==0) else "Helvetica"))
      for j,c in enumerate(r)] for i,r in enumerate(care_data)],
    colWidths=[4.5*cm, 11.7*cm], repeatRows=1
)
care_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREEN),
    ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#BDC3C7")),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_GREEN]),
    ("TOPPADDING", (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING", (0,0), (-1,-1), 8),
    ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("BACKGROUND", (0,1), (0,-1), LIGHT_GREEN),
    ("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"),
    ("TEXTCOLOR", (0,1), (0,-1), GREEN),
]))
story.append(care_table)
story.append(Spacer(1, 0.4*cm))

story.append(section_header("SECONDARY PREVENTION (Preventing Another Stroke)", bg=MED_BLUE))
story.append(Spacer(1, 0.3*cm))

sp_rows = [
    ["Risk Factor", "Target / Intervention"],
    ["Hypertension", "Target BP < 130/80. ACE inhibitors or ARBs preferred."],
    ["Hyperlipidaemia", "Statin therapy — target LDL < 70 mg/dL. High-intensity statin (Atorvastatin 40–80 mg)."],
    ["Atrial Fibrillation", "Long-term anticoagulation: NOACs (Apixaban, Rivaroxaban) preferred over Warfarin."],
    ["Carotid Stenosis > 70%", "Carotid endarterectomy (CEA) or carotid artery stenting (CAS) within 2 weeks."],
    ["Diabetes", "Good glycaemic control. HbA1c < 7%."],
    ["Lifestyle", "Stop smoking, reduce alcohol, exercise (150 min/week), weight loss, Mediterranean diet."],
    ["Antiplatelet therapy", "Aspirin 75 mg daily lifelong (ischemic stroke without AF). DAPT for 21 days after high-risk TIA/minor stroke."],
]
sp_table = Table(
    [[Paragraph(str(c), make_style(f"sp{i}{j}", fontSize=9, leading=12,
                                   textColor=WHITE if i==0 else DARK_BLUE,
                                   fontName="Helvetica-Bold" if (i==0 or j==0) else "Helvetica"))
      for j,c in enumerate(r)] for i,r in enumerate(sp_rows)],
    colWidths=[5.5*cm, 10.7*cm], repeatRows=1
)
sp_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), MED_BLUE),
    ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#BDC3C7")),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_BLUE]),
    ("TOPPADDING", (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING", (0,0), (-1,-1), 8),
    ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("BACKGROUND", (0,1), (0,-1), LIGHT_BLUE),
    ("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"),
    ("TEXTCOLOR", (0,1), (0,-1), MED_BLUE),
]))
story.append(sp_table)
story.append(PageBreak())


# ─────────── PAGE 10: SUMMARY QUICK REFERENCE ────────────────────────────────
story.append(section_header("QUICK REFERENCE SUMMARY", bg=DARK_BLUE))
story.append(Spacer(1, 0.3*cm))

# Summary decision table
summ_rows = [
    ["Time Since Onset", "NCCT Result", "Action", "Drug"],
    ["< 4.5 hours", "No hemorrhage", "IV Thrombolysis", "Alteplase 0.9 mg/kg or Tenectaplase 0.25 mg/kg"],
    ["< 4.5 hours + LVO", "No hemorrhage", "Thrombolysis + Thrombectomy", "rtPA + Mechanical thrombectomy"],
    ["4.5 – 24 hours", "No hemorrhage (DWI mismatch)", "Consider thrombectomy if LVO", "Thrombectomy if penumbra present"],
    ["> 24 hours", "No hemorrhage", "Medical management", "Aspirin ± Clopidogrel"],
    ["Any time", "Hemorrhage on CT", "Hemorrhagic stroke protocol", "NO rtPA. BP control, Neurosurgery"],
    ["High-risk TIA", "Normal / minor", "DAPT urgently", "Aspirin + Clopidogrel × 21 days"],
    ["AF / Cardioembolic", "No hemorrhage", "Anticoagulation", "NOAC or Heparin → Warfarin"],
]
s_table = Table(
    [[Paragraph(str(c), make_style(f"sm{i}{j}", fontSize=9, leading=12,
                                   textColor=WHITE if i==0 else DARK_BLUE,
                                   fontName="Helvetica-Bold" if i==0 else "Helvetica"))
      for j,c in enumerate(r)] for i,r in enumerate(summ_rows)],
    colWidths=[3.5*cm, 3.5*cm, 4*cm, 5.2*cm], repeatRows=1
)
row_bgs = [LIGHT_GREEN, LIGHT_GREEN, LIGHT_ORANGE, LIGHT_GRAY, LIGHT_RED, LIGHT_YELLOW, LIGHT_BLUE]
s_ts = [
    ("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
    ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#BDC3C7")),
    ("TOPPADDING", (0,0), (-1,-1), 6),
    ("BOTTOMPADDING", (0,0), (-1,-1), 6),
    ("LEFTPADDING", (0,0), (-1,-1), 8),
    ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]
for idx, bg in enumerate(row_bgs):
    s_ts.append(("BACKGROUND", (0, idx+1), (-1, idx+1), bg))
s_table.setStyle(TableStyle(s_ts))
story.append(s_table)
story.append(Spacer(1, 0.4*cm))

# Key mnemonics
story.append(Paragraph("Key Mnemonics & Memory Aids", H2_S))
mnem_data = [
    [
        Paragraph("<b>BE-FAST</b>\n(Stroke Recognition)", make_style("mn1", fontSize=10, fontName="Helvetica-Bold", textColor=RED)),
        Paragraph("<b>CI of rtPA</b>\n(BBRR)", make_style("mn2", fontSize=10, fontName="Helvetica-Bold", textColor=ORANGE)),
        Paragraph("<b>Time Targets</b>", make_style("mn3", fontSize=10, fontName="Helvetica-Bold", textColor=GREEN)),
    ],
    [
        Paragraph("B - Balance\nE - Eye\nF - Face\nA - Arm\nS - Speech\nT - Time (call 999!)",
                  make_style("mn1b", fontSize=9, leading=13)),
        Paragraph("B - BP > 185/110\nB - Bleeding disorder\nR - Recent hemorrhagic stroke\nR - Rapidly improving (TIA)",
                  make_style("mn2b", fontSize=9, leading=13)),
        Paragraph("Door-to-CT: ≤ 25 min\nDoor-to-needle (rtPA): ≤ 60 min\nDoor-to-groin (thrombectomy): ≤ 90 min\nTime window: 4.5 hrs (rtPA), 24 hrs (thrombectomy)",
                  make_style("mn3b", fontSize=9, leading=13)),
    ]
]
mnem_table = Table(mnem_data, colWidths=[(PAGE_W-2*MARGIN-1*cm)/3]*3, hAlign="CENTER")
mnem_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (0,-1), LIGHT_RED),
    ("BACKGROUND", (1,0), (1,-1), LIGHT_ORANGE),
    ("BACKGROUND", (2,0), (2,-1), LIGHT_GREEN),
    ("BOX", (0,0), (0,-1), 1.5, RED),
    ("BOX", (1,0), (1,-1), 1.5, ORANGE),
    ("BOX", (2,0), (2,-1), 1.5, GREEN),
    ("TOPPADDING", (0,0), (-1,-1), 8),
    ("BOTTOMPADDING", (0,0), (-1,-1), 8),
    ("LEFTPADDING", (0,0), (-1,-1), 8),
    ("RIGHTPADDING", (0,0), (-1,-1), 8),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("COLPADDING", (0,0), (-1,-1), 4),
]))
story.append(mnem_table)
story.append(Spacer(1, 0.4*cm))

story.append(HRFlowable(width="100%", thickness=1, color=LIGHT_GRAY, spaceAfter=8))
story.append(Paragraph(
    "Reference: Bradley and Daroff's Neurology in Clinical Practice | AHA/ASA Stroke Guidelines 2019/2023 | "
    "DAMS Medicine Neurology Notes (Page 266)",
    Small_S))
story.append(Paragraph(
    "This document is for educational use only. Clinical decisions must be based on individual patient "
    "assessment and current institutional protocols.",
    make_style("disc", fontSize=7.5, textColor=RED, fontName="Helvetica-Oblique", alignment=TA_CENTER)))


# ── Build ──────────────────────────────────────────────────────────────────────
doc.build(story, onFirstPage=on_first_page, onLaterPages=on_later_pages)
print(f"\nPDF created: {OUT}")
print(f"File size: {os.path.getsize(OUT)/1024:.1f} KB")
Running Command

cd /tmp/workspace/cva-pdf && python3 build_cva_pdf.py 2>&1

Your comprehensive CVA Management PDF is ready!

CVA Management Guide

PDF Document · PDF


Here is what the PDF contains across 10 fully formatted pages:
Page 1 - Cover Page
  • Full BE-FAST recognition graphic with color-coded boxes
  • "Time is Brain" motto
Page 2 - What is a Stroke?
  • Ischemic vs Hemorrhagic stroke comparison
  • TIA explanation
  • Modifiable vs non-modifiable risk factors table
Page 3 - Initial Recognition & Assessment
  • Detailed BE-FAST table with quick bedside tests
  • NIHSS severity scoring table
Page 4 - Main Management Flowchart
  • Complete decision tree: Clinical suspicion → NCCT → onset time → < 4.5h / 4.5-24h / > 24h branches → rtPA → no response → cerebral angiography → LVO → mechanical thrombectomy
Page 5 - Emergency Imaging
  • Real NCCT brain image (hemorrhage exclusion) with labeled findings
  • Real DWI MRI image (penumbra vs infarct core)
  • Imaging comparison table (NCCT, CTA, MRI DWI, DSA)
Page 6 - Thrombolysis (rtPA)
  • Dosing protocol box (Alteplase + Tenectaplase)
  • Full contraindications table (9 CIs with reasons)
  • Post-rtPA monitoring protocol
Page 7 - Mechanical Thrombectomy
  • Real cerebral angiography image (pre/post thrombectomy with stent retriever photo)
  • Eligibility criteria box
  • Cerebral vessel territories table (ICA, MCA, ACA, PCA, Basilar, PICA)
Page 8 - Drug Therapy
  • Full drug table (7 drugs with doses and indications)
  • Scenario-based treatment guide
  • BP management targets table
Page 9 - General Care & Secondary Prevention
  • Acute nursing/medical care table (9 systems)
  • Secondary prevention table (7 risk factors)
Page 10 - Quick Reference Summary
  • One-page summary decision table by time window
  • BE-FAST, CI mnemonics, and time targets cards side by side
This is a shared conversation. Sign in to Orris to start your own chat.