attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment
attachment

I dont know about this topics. I want to easily understand about this topic in easy language with flowsheet and with diagram also. Provide me a pdf that contains all the topic along with diagram and flowsheet diagram

I can see the screenshots are from Chapter 3: Wound Healing and Tissue Repair. Let me analyze all the images first, then create a comprehensive, easy-to-understand PDF with flowcharts and diagrams.
Reading File
Good. I have the PDF skill instructions. Now I have all the content from the images (visible in the attachments). Let me create the comprehensive PDF directly using ReportLab with all the content, diagrams drawn in Python, and flowcharts.
Running Command

mkdir -p /home/daytona/workspace/wound-healing && ls /home/daytona/workspace/wound-healing/

Writing File

~/wound-healing/create_pdf.py

"""
Wound Healing and Tissue Repair - Comprehensive Study Guide PDF
Using ReportLab for all content, diagrams, and flowcharts
"""

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    PageBreak, HRFlowable, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Polygon, Circle, Arrow
from reportlab.graphics import renderPDF
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Group, Path
import math

# ─── Color Palette ──────────────────────────────────────────────────────────
C_DARK    = colors.HexColor('#1A1A2E')   # deep navy
C_PRIMARY = colors.HexColor('#C0392B')   # medical red
C_SEC     = colors.HexColor('#E67E22')   # amber
C_ACCENT  = colors.HexColor('#2980B9')   # blue
C_GREEN   = colors.HexColor('#27AE60')   # green
C_LIGHT   = colors.HexColor('#FAF0E6')   # linen
C_BOX     = colors.HexColor('#FFF3E0')   # light amber
C_BLUE_LT = colors.HexColor('#EBF5FB')   # light blue
C_RED_LT  = colors.HexColor('#FDEDEC')   # light red
C_GRAY    = colors.HexColor('#7F8C8D')   # gray
C_WHITE   = colors.white

PAGE_W, PAGE_H = A4
MARGIN = 2*cm

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

def style(name, **kw):
    s = ParagraphStyle(name, **kw)
    return s

TITLE_S = style('MyTitle',
    fontName='Helvetica-Bold', fontSize=28, textColor=C_WHITE,
    alignment=TA_CENTER, spaceAfter=6)

H1 = style('MyH1',
    fontName='Helvetica-Bold', fontSize=16, textColor=C_PRIMARY,
    spaceBefore=14, spaceAfter=6)

H2 = style('MyH2',
    fontName='Helvetica-Bold', fontSize=13, textColor=C_DARK,
    spaceBefore=10, spaceAfter=4)

H3 = style('MyH3',
    fontName='Helvetica-Bold', fontSize=11, textColor=C_ACCENT,
    spaceBefore=8, spaceAfter=3)

BODY = style('MyBody',
    fontName='Helvetica', fontSize=10, textColor=C_DARK,
    leading=15, spaceAfter=5, alignment=TA_JUSTIFY)

BULLET = style('MyBullet',
    fontName='Helvetica', fontSize=10, textColor=C_DARK,
    leading=14, leftIndent=14, spaceAfter=3)

CAPTION = style('MyCaption',
    fontName='Helvetica-Oblique', fontSize=9, textColor=C_GRAY,
    alignment=TA_CENTER, spaceBefore=3, spaceAfter=8)

NOTE_S = style('MyNote',
    fontName='Helvetica', fontSize=9, textColor=colors.HexColor('#555555'),
    leading=13, leftIndent=8)

# ─── Helper Flowables ────────────────────────────────────────────────────────

class ColorBox(Flowable):
    """Colored background box with title + body text."""
    def __init__(self, title, body_lines, bg=C_BOX, title_color=C_PRIMARY, width=None):
        super().__init__()
        self.title = title
        self.body_lines = body_lines
        self.bg = bg
        self.title_color = title_color
        self._width = width or (PAGE_W - 2*MARGIN)
        self._calc_height()

    def _calc_height(self):
        self._height = 14 + len(self.body_lines)*14 + 12

    def wrap(self, avW, avH):
        self._width = min(self._width, avW)
        return self._width, self._height

    def draw(self):
        c = self.canv
        w, h = self._width, self._height
        # shadow
        c.setFillColor(colors.HexColor('#CCCCCC'))
        c.roundRect(3, -3, w, h, 6, fill=1, stroke=0)
        # box
        c.setFillColor(self.bg)
        c.setStrokeColor(self.title_color)
        c.setLineWidth(1.5)
        c.roundRect(0, 0, w, h, 6, fill=1, stroke=1)
        # title bar
        c.setFillColor(self.title_color)
        c.roundRect(0, h-18, w, 18, 6, fill=1, stroke=0)
        c.rect(0, h-18, w, 10, fill=1, stroke=0)
        # title text
        c.setFillColor(C_WHITE)
        c.setFont('Helvetica-Bold', 10)
        c.drawString(8, h-13, self.title)
        # body
        c.setFillColor(C_DARK)
        c.setFont('Helvetica', 9)
        y = h - 28
        for line in self.body_lines:
            c.drawString(10, y, line)
            y -= 13


class SectionBanner(Flowable):
    """Full-width section header banner."""
    def __init__(self, text, color=C_PRIMARY, width=None):
        super().__init__()
        self.text = text
        self.color = color
        self._width = width or (PAGE_W - 2*MARGIN)
        self._height = 32

    def wrap(self, avW, avH):
        self._width = min(self._width, avW)
        return self._width, self._height

    def draw(self):
        c = self.canv
        c.setFillColor(self.color)
        c.roundRect(0, 0, self._width, self._height, 5, fill=1, stroke=0)
        c.setFillColor(C_WHITE)
        c.setFont('Helvetica-Bold', 14)
        c.drawString(12, 10, self.text)


class WoundHealingPhaseDiagram(Flowable):
    """Visual diagram of the 4 phases of wound healing as timeline."""
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 2*MARGIN)
        self._height = 160

    def wrap(self, avW, avH):
        self._width = min(self._width, avW)
        return self._width, self._height

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

        phases = [
            ('HAEMOSTASIS', '0-30 min', C_PRIMARY, '• Vasoconstriction\n• Platelet plug\n• Clot formation'),
            ('INFLAMMATION', 'Day 1-5', colors.HexColor('#E67E22'), '• Neutrophils (day 1-2)\n• Macrophages (day 2-3)\n• Clean the wound'),
            ('PROLIFERATION', 'Day 3 - 3wks', colors.HexColor('#2980B9'), '• Fibroblasts\n• New collagen\n• Angiogenesis'),
            ('REMODELLING', '3wks - 2yrs', colors.HexColor('#27AE60'), '• Collagen matures\n• Scar strengthens\n• 80% strength'),
        ]

        n = len(phases)
        box_w = (w - 20) / n - 8
        box_h = 110
        y_base = 20

        for i, (name, timing, col, details) in enumerate(phases):
            x = 10 + i * (box_w + 8)
            # shadow
            c.setFillColor(colors.HexColor('#BBBBBB'))
            c.roundRect(x+3, y_base-3, box_w, box_h, 8, fill=1, stroke=0)
            # main box
            c.setFillColor(col)
            c.roundRect(x, y_base, box_w, box_h, 8, fill=1, stroke=0)
            # phase number circle
            c.setFillColor(C_WHITE)
            c.circle(x + box_w/2, y_base + box_h - 14, 12, fill=1, stroke=0)
            c.setFillColor(col)
            c.setFont('Helvetica-Bold', 11)
            c.drawCentredString(x + box_w/2, y_base + box_h - 18, str(i+1))
            # title
            c.setFillColor(C_WHITE)
            c.setFont('Helvetica-Bold', 8)
            c.drawCentredString(x + box_w/2, y_base + box_h - 32, name)
            # timing
            c.setFont('Helvetica-Oblique', 7.5)
            c.setFillColor(colors.HexColor('#FFECB3'))
            c.drawCentredString(x + box_w/2, y_base + box_h - 44, timing)
            # details
            c.setFillColor(C_WHITE)
            c.setFont('Helvetica', 7.5)
            lines = details.split('\n')
            for j, ln in enumerate(lines):
                c.drawString(x + 6, y_base + box_h - 58 - j*13, ln)

            # arrow between boxes
            if i < n-1:
                ax = x + box_w + 2
                ay = y_base + box_h/2
                c.setFillColor(C_GRAY)
                c.setStrokeColor(C_GRAY)
                c.setLineWidth(1.5)
                c.line(ax, ay, ax+6, ay)
                # arrowhead
                c.setFillColor(C_GRAY)
                pts = [ax+6, ay+4, ax+6, ay-4, ax+10, ay]
                c.setFillColor(C_GRAY)
                p = c.beginPath()
                p.moveTo(ax+6, ay+4)
                p.lineTo(ax+6, ay-4)
                p.lineTo(ax+10, ay)
                p.close()
                c.drawPath(p, fill=1, stroke=0)

        # timeline bar at bottom
        c.setFillColor(colors.HexColor('#ECF0F1'))
        c.rect(10, y_base - 14, w-20, 10, fill=1, stroke=0)
        c.setFillColor(C_DARK)
        c.setFont('Helvetica-Bold', 7)
        c.drawCentredString(w/2, y_base - 9, 'TIME PROGRESSION →')


class CoagulationCascadeDiagram(Flowable):
    """Simplified coagulation cascade flowchart."""
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 2*MARGIN)
        self._height = 320

    def wrap(self, avW, avH):
        self._width = min(self._width, avW)
        return self._width, self._height

    def _box(self, c, x, y, w, h, text, bg, fg=None, font_size=8):
        fg = fg or C_WHITE
        c.setFillColor(bg)
        c.roundRect(x, y, w, h, 5, fill=1, stroke=0)
        c.setFillColor(fg)
        c.setFont('Helvetica-Bold', font_size)
        lines = text.split('\n')
        total_h = len(lines) * (font_size + 2)
        start_y = y + h/2 + total_h/2 - font_size
        for i, ln in enumerate(lines):
            c.drawCentredString(x + w/2, start_y - i*(font_size+2), ln)

    def _arrow(self, c, x1, y1, x2, y2, color=None):
        color = color or C_DARK
        c.setStrokeColor(color)
        c.setLineWidth(1.2)
        c.line(x1, y1, x2, y2)
        # arrowhead
        angle = math.atan2(y2-y1, x2-x1)
        size = 6
        ax = x2 - size*math.cos(angle-0.4)
        ay = y2 - size*math.sin(angle-0.4)
        bx = x2 - size*math.cos(angle+0.4)
        by = y2 - size*math.sin(angle+0.4)
        c.setFillColor(color)
        p = c.beginPath()
        p.moveTo(x2, y2)
        p.lineTo(ax, ay)
        p.lineTo(bx, by)
        p.close()
        c.drawPath(p, fill=1, stroke=0)

    def draw(self):
        c = self.canv
        w = self._width
        bw = 110  # box width
        bh = 28   # box height
        cx = w / 2

        # Title
        c.setFillColor(C_DARK)
        c.setFont('Helvetica-Bold', 11)
        c.drawCentredString(cx, self._height - 14, 'COAGULATION CASCADE (Simplified)')

        # Row positions (y)
        y_top = self._height - 45
        y2 = y_top - 50
        y3 = y2 - 50
        y4 = y3 - 50
        y5 = y4 - 50
        y6 = y5 - 50

        # Intrinsic pathway (left)
        lx = 20
        self._box(c, lx, y_top, bw, bh, 'INTRINSIC PATHWAY\n(Contact Activation)', colors.HexColor('#C0392B'))
        self._box(c, lx, y2, bw, bh, 'Factor XII → XIIa\nFactor XI → XIa', colors.HexColor('#E74C3C'))
        self._box(c, lx, y3, bw, bh, 'Factor IX → IXa\n(with Factor VIII)', colors.HexColor('#E74C3C'))

        # Extrinsic pathway (right)
        rx = w - lx - bw
        self._box(c, rx, y_top, bw, bh, 'EXTRINSIC PATHWAY\n(Tissue Damage)', colors.HexColor('#2980B9'))
        self._box(c, rx, y2, bw, bh, 'Tissue Factor released\n+ Factor VII → VIIa', colors.HexColor('#3498DB'))
        self._box(c, rx, y3, bw, bh, 'Factor X activated\nby VIIa-TF complex', colors.HexColor('#3498DB'))

        # Common pathway (centre)
        cbox_x = cx - bw/2
        self._box(c, cbox_x, y3, bw, bh, 'COMMON PATHWAY\nFactor X → Xa', colors.HexColor('#8E44AD'))
        self._box(c, cbox_x, y4, bw, bh, 'Factor II (Prothrombin)\n→ IIa (Thrombin)', colors.HexColor('#9B59B6'))
        self._box(c, cbox_x, y5, bw, bh, 'Fibrinogen → Fibrin\n(Factor XIII cross-links)', colors.HexColor('#6C3483'))

        # Final result
        self._box(c, cbox_x, y6, bw, bh, 'STABLE BLOOD CLOT\n(Haemostasis achieved)', colors.HexColor('#1E8449'))

        # Arrows - Intrinsic
        self._arrow(c, lx+bw/2, y_top, lx+bw/2, y2+bh, C_PRIMARY)
        self._arrow(c, lx+bw/2, y2, lx+bw/2, y3+bh, C_PRIMARY)
        self._arrow(c, lx+bw, y3+bh/2, cbox_x, y3+bh/2, colors.HexColor('#8E44AD'))

        # Arrows - Extrinsic
        self._arrow(c, rx+bw/2, y_top, rx+bw/2, y2+bh, C_ACCENT)
        self._arrow(c, rx+bw/2, y2, rx+bw/2, y3+bh, C_ACCENT)
        self._arrow(c, rx, y3+bh/2, cbox_x+bw, y3+bh/2, colors.HexColor('#8E44AD'))

        # Arrows - Common
        self._arrow(c, cx, y3, cx, y4+bh, colors.HexColor('#8E44AD'))
        self._arrow(c, cx, y4, cx, y5+bh, colors.HexColor('#6C3483'))
        self._arrow(c, cx, y5, cx, y6+bh, colors.HexColor('#1E8449'))

        # Labels on arrows
        c.setFillColor(C_GRAY)
        c.setFont('Helvetica-Oblique', 7)
        c.drawCentredString(cx, y3+bh+6, 'Both pathways converge here')


class WoundTypesFlowchart(Flowable):
    """Flowchart for types of wound healing."""
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 2*MARGIN)
        self._height = 280

    def wrap(self, avW, avH):
        self._width = min(self._width, avW)
        return self._width, self._height

    def _box(self, c, x, y, w, h, text, bg, fg=C_WHITE, fs=9, radius=5):
        c.setFillColor(bg)
        c.roundRect(x, y, w, h, radius, fill=1, stroke=0)
        c.setFillColor(fg)
        c.setFont('Helvetica-Bold', fs)
        lines = text.split('\n')
        total = len(lines)*(fs+2)
        sy = y + h/2 + total/2 - fs
        for i, ln in enumerate(lines):
            c.drawCentredString(x+w/2, sy - i*(fs+2), ln)

    def _arrow(self, c, x1, y1, x2, y2, label='', col=None):
        col = col or C_DARK
        c.setStrokeColor(col)
        c.setLineWidth(1.2)
        c.line(x1, y1, x2, y2)
        ang = math.atan2(y2-y1, x2-x1)
        sz = 6
        ax = x2 - sz*math.cos(ang-0.4)
        ay = y2 - sz*math.sin(ang-0.4)
        bx = x2 - sz*math.cos(ang+0.4)
        by = y2 - sz*math.sin(ang+0.4)
        c.setFillColor(col)
        p = c.beginPath()
        p.moveTo(x2, y2); p.lineTo(ax, ay); p.lineTo(bx, by); p.close()
        c.drawPath(p, fill=1, stroke=0)
        if label:
            mx, my = (x1+x2)/2, (y1+y2)/2
            c.setFillColor(C_GRAY)
            c.setFont('Helvetica-Oblique', 7.5)
            c.drawCentredString(mx+5, my+3, label)

    def draw(self):
        c = self.canv
        w = self._width
        bw = 120; bh = 32
        cx = w/2
        y0 = self._height - 20

        # Start: Wound occurs
        self._box(c, cx-60, y0-bh, 120, bh, 'WOUND OCCURS', C_DARK)
        self._arrow(c, cx, y0-bh, cx, y0-bh-20)

        # Decision: wound edges
        qx = cx - 90; qw = 180; qh = 36
        self._box(c, qx, y0-bh-20-qh, qw, qh, 'Are wound edges\nclosely together?',
                  colors.HexColor('#F39C12'), fg=C_WHITE, fs=9)
        y_q = y0-bh-20-qh

        # YES -> Primary
        self._arrow(c, qx, y_q+qh/2, qx-10, y_q+qh/2)
        px = 10; py = y_q - 60
        self._box(c, px, py, 130, 55,
                  'PRIMARY HEALING\n(1st Intention)\n\nEdges joined\nMinimal scar', C_GREEN)
        self._arrow(c, qx, y_q+qh/2, px+130, y_q+qh/2, 'YES', C_GREEN)
        self._arrow(c, px+65, y_q+qh/2, px+65, py+55, C_GREEN)

        # NO -> Secondary
        rx = w - 140; ry = y_q - 60
        self._box(c, rx, ry, 130, 55,
                  'SECONDARY HEALING\n(2nd Intention)\n\nLeft open\nHeals by granulation', C_ACCENT)
        self._arrow(c, qx+qw, y_q+qh/2, rx, y_q+qh/2, 'NO', C_ACCENT)
        self._arrow(c, rx+65, y_q+qh/2, rx+65, ry+55, C_ACCENT)

        # Tertiary
        tx = cx - 65; ty = y_q - 140
        self._box(c, tx, ty, 130, 45,
                  'TERTIARY HEALING\n(Delayed 1st Intention)\n\nInitially open,\nclosed later', C_SEC)
        self._arrow(c, cx, y_q, cx, ty+45)

        # Outcome boxes
        self._box(c, px, py-50, 130, 30, 'OUTCOME:\nLeast scarring', colors.HexColor('#A9DFBF'), fg=C_DARK, fs=8)
        self._arrow(c, px+65, py, px+65, py-20, C_GREEN)

        self._box(c, rx, ry-50, 130, 30, 'OUTCOME:\nMore scarring', colors.HexColor('#AED6F1'), fg=C_DARK, fs=8)
        self._arrow(c, rx+65, ry, rx+65, ry-20, C_ACCENT)


class WoundClassificationTable(Flowable):
    """Visual wound classification table."""
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 2*MARGIN)
        self._height = 180

    def wrap(self, avW, avH):
        self._width = min(self._width, avW)
        return self._width, self._height

    def draw(self):
        c = self.canv
        w = self._width
        cols = [
            ('CLASS I\nCLEAN', 'No inflammation\nRespiratory/GI/GU tracts\nnot entered', colors.HexColor('#27AE60')),
            ('CLASS II\nCLEAN-CONTAM.', 'Respiratory/GI entered\nunder controlled conditions\nNo infection', colors.HexColor('#F39C12')),
            ('CLASS III\nCONTAMINATED', 'Open fresh wounds\nMajor breaks in sterile\ntechnique', colors.HexColor('#E67E22')),
            ('CLASS IV\nDIRTY', 'Old traumatic wounds\nDevitalised tissue\nExisting infection', colors.HexColor('#C0392B')),
        ]
        col_w = (w - 20) / 4
        for i, (title, desc, col) in enumerate(cols):
            x = 10 + i*col_w
            # header
            c.setFillColor(col)
            c.roundRect(x, self._height-50, col_w-5, 45, 6, fill=1, stroke=0)
            c.setFillColor(C_WHITE)
            c.setFont('Helvetica-Bold', 8)
            lines = title.split('\n')
            c.drawCentredString(x+col_w/2-2, self._height-22, lines[0])
            if len(lines) > 1:
                c.drawCentredString(x+col_w/2-2, self._height-33, lines[1])
            # risk level
            risk_labels = ['LOW RISK', 'MOD RISK', 'HIGH RISK', 'VERY HIGH']
            risk_cols = [colors.HexColor('#A9DFBF'), colors.HexColor('#FAD7A0'),
                         colors.HexColor('#FAD7A0'), colors.HexColor('#F1948A')]
            c.setFillColor(risk_cols[i])
            c.roundRect(x, self._height-55, col_w-5, 10, 3, fill=1, stroke=0)
            c.setFillColor(C_DARK)
            c.setFont('Helvetica-Bold', 6.5)
            c.drawCentredString(x+col_w/2-2, self._height-49, risk_labels[i])
            # body
            c.setFillColor(colors.HexColor('#F8F9FA'))
            c.roundRect(x, self._height-55-110, col_w-5, 108, 4, fill=1, stroke=0)
            c.setFillColor(C_DARK)
            c.setFont('Helvetica', 7.5)
            desc_lines = desc.split('\n')
            for j, ln in enumerate(desc_lines):
                c.drawString(x+5, self._height-75-j*14, '• ' + ln)
            # SSI risk %
            risks = ['1-5%', '3-11%', '10-17%', '>27%']
            c.setFillColor(col)
            c.setFont('Helvetica-Bold', 9)
            c.drawCentredString(x+col_w/2-2, self._height-55-100, f'SSI: {risks[i]}')


class AbnormalWoundFlowchart(Flowable):
    """Flowchart for abnormal wound healing."""
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 2*MARGIN)
        self._height = 250

    def _box(self, c, x, y, w, h, text, bg, fg=C_WHITE, fs=8.5):
        c.setFillColor(bg)
        c.roundRect(x, y, w, h, 5, fill=1, stroke=0)
        c.setFillColor(fg)
        c.setFont('Helvetica-Bold', fs)
        lines = text.split('\n')
        total = len(lines)*(fs+2)
        sy = y + h/2 + total/2 - fs
        for i, ln in enumerate(lines):
            c.drawCentredString(x+w/2, sy-i*(fs+2), ln)

    def _arrow(self, c, x1,y1,x2,y2, col=None):
        col = col or C_DARK
        c.setStrokeColor(col); c.setLineWidth(1.2); c.line(x1,y1,x2,y2)
        ang = math.atan2(y2-y1,x2-x1); sz=6
        ax=x2-sz*math.cos(ang-0.4); ay=y2-sz*math.sin(ang-0.4)
        bx=x2-sz*math.cos(ang+0.4); by=y2-sz*math.sin(ang+0.4)
        c.setFillColor(col); p=c.beginPath()
        p.moveTo(x2,y2);p.lineTo(ax,ay);p.lineTo(bx,by);p.close()
        c.drawPath(p,fill=1,stroke=0)

    def wrap(self, avW, avH):
        self._width = min(self._width, avW)
        return self._width, self._height

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

        # Top box
        self._box(c, cx-90, self._height-40, 180, 32, 'WOUND FAILS TO HEAL\nNORMALLY', C_PRIMARY)
        self._arrow(c, cx, self._height-40, cx, self._height-40-20)

        # Two branches: Local & Systemic
        branch_y = self._height - 110
        self._box(c, 10, branch_y, 160, 32, 'LOCAL FACTORS', colors.HexColor('#C0392B'))
        self._box(c, w-170, branch_y, 160, 32, 'SYSTEMIC FACTORS', colors.HexColor('#2980B9'))
        self._arrow(c, cx, self._height-40-20, 90, branch_y+32, C_PRIMARY)
        self._arrow(c, cx, self._height-40-20, w-90, branch_y+32, C_PRIMARY)

        # Local factor details
        local = ['Skin tension', 'Hypoxia', 'Vascular insufficiency',
                 'Infection', 'Foreign bodies', 'Radiotherapy']
        c.setFillColor(colors.HexColor('#FDEDEC'))
        c.roundRect(10, branch_y-100, 160, 98, 5, fill=1, stroke=0)
        c.setFillColor(C_DARK); c.setFont('Helvetica', 8)
        for i, f in enumerate(local):
            c.drawString(16, branch_y-14-i*13, '• ' + f)

        # Systemic factor details
        systemic = ['Advancing age', 'Obesity', 'Malnutrition', 'Smoking',
                    'Diabetes mellitus', 'Immunocompromised', 'Chemotherapy']
        c.setFillColor(colors.HexColor('#EBF5FB'))
        c.roundRect(w-170, branch_y-100, 160, 98, 5, fill=1, stroke=0)
        c.setFillColor(C_DARK); c.setFont('Helvetica', 8)
        for i, f in enumerate(systemic):
            c.drawString(w-165, branch_y-14-i*13, '• ' + f)

        # Result
        self._box(c, cx-100, 15, 200, 32, 'CHRONIC / POOR HEALING\nHypertrophic / Keloid Scar', colors.HexColor('#7D3C98'))
        self._arrow(c, 90, branch_y, cx, 47, C_PRIMARY)
        self._arrow(c, w-90, branch_y, cx, 47, C_ACCENT)


class ScarTypeDiagram(Flowable):
    """Visual comparison of scar types."""
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 2*MARGIN)
        self._height = 160

    def wrap(self, avW, avH):
        self._width = min(self._width, avW)
        return self._width, self._height

    def draw(self):
        c = self.canv
        w = self._width
        types = [
            ('NORMAL SCAR', C_GREEN,
             ['Within wound boundary', 'Flat after maturation', 'No recurrence', 'Fades over time']),
            ('HYPERTROPHIC SCAR', colors.HexColor('#E67E22'),
             ['Raised but within wound', 'Red/itchy initially', 'Regresses over time', 'More common']),
            ('KELOID SCAR', C_PRIMARY,
             ['Extends beyond wound!', 'Does NOT regress', 'Dark skin predisposition', 'Difficult to treat']),
        ]
        col_w = (w - 20) / 3
        for i, (name, col, details) in enumerate(types):
            x = 10 + i * col_w
            h_top = self._height - 10

            # Scar shape illustration
            c.setFillColor(colors.HexColor('#F5CBA7'))
            c.roundRect(x+5, h_top-50, col_w-15, 40, 5, fill=1, stroke=0)
            # wound line
            c.setStrokeColor(colors.HexColor('#922B21'))
            c.setLineWidth(2)
            wound_cx = x + col_w/2 - 5
            c.line(wound_cx, h_top-15, wound_cx, h_top-45)
            # scar bulge representation
            if i == 0:  # normal: thin line
                c.setFillColor(colors.HexColor('#E74C3C'))
                c.rect(wound_cx-1, h_top-15, 2, 30, fill=1, stroke=0)
            elif i == 1:  # hypertrophic: raised but contained
                c.setFillColor(colors.HexColor('#E74C3C'))
                c.ellipse(wound_cx-5, h_top-45, wound_cx+5, h_top-12, fill=1, stroke=0)
            else:  # keloid: extends beyond
                c.setFillColor(colors.HexColor('#E74C3C'))
                c.ellipse(wound_cx-15, h_top-50, wound_cx+15, h_top-10, fill=1, stroke=0)

            # header
            c.setFillColor(col)
            c.roundRect(x+5, h_top-60, col_w-15, 12, 3, fill=1, stroke=0)
            c.setFillColor(C_WHITE); c.setFont('Helvetica-Bold', 7.5)
            c.drawCentredString(wound_cx, h_top-52, name)

            # details
            c.setFillColor(colors.HexColor('#F8F9FA'))
            c.roundRect(x+5, h_top-60-65, col_w-15, 63, 4, fill=1, stroke=0)
            c.setFillColor(C_DARK); c.setFont('Helvetica', 7.5)
            for j, d in enumerate(details):
                c.drawString(x+10, h_top-75-j*13, '• '+d)


class PressureUlcerStaging(Flowable):
    """Visual pressure ulcer staging diagram."""
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 2*MARGIN)
        self._height = 180

    def wrap(self, avW, avH):
        self._width = min(self._width, avW)
        return self._width, self._height

    def draw(self):
        c = self.canv
        w = self._width
        stages = [
            ('STAGE 1', 'Non-blanchable\nredness\nIntact skin', colors.HexColor('#F9E79F')),
            ('STAGE 2', 'Partial thickness\nSkin loss\nShallow ulcer', colors.HexColor('#FAD7A0')),
            ('STAGE 3', 'Full thickness\nSkin loss\nSubcut. visible', colors.HexColor('#F0B27A')),
            ('STAGE 4', 'Full thickness\nBone/tendon\nvisible', colors.HexColor('#E59866')),
            ('UNSTAGEABLE', 'Depth unknown\nSlough covers\nwound', colors.HexColor('#CA6F1E')),
        ]
        col_w = (w - 20) / 5
        for i, (stage, desc, col) in enumerate(stages):
            x = 10 + i*col_w
            bh = 145

            c.setFillColor(col)
            c.roundRect(x, 15, col_w-8, bh, 6, fill=1, stroke=0)

            # Skin cross-section illustration
            skin_y = 15 + bh - 50
            # Epidermis
            c.setFillColor(colors.HexColor('#F5CBA7'))
            c.rect(x+4, skin_y+20, col_w-16, 12, fill=1, stroke=0)
            # Dermis
            c.setFillColor(colors.HexColor('#FADBD8'))
            c.rect(x+4, skin_y+8, col_w-16, 12, fill=1, stroke=0)
            # Subcut
            c.setFillColor(colors.HexColor('#FDEBD0'))
            c.rect(x+4, skin_y-2, col_w-16, 10, fill=1, stroke=0)

            # Damage visualization
            dmg_col = colors.HexColor('#C0392B')
            if i == 0:  # Stage 1 - red area
                c.setFillColor(dmg_col)
                c.rect(x+10, skin_y+28, col_w-24, 4, fill=1, stroke=0)
            elif i == 1:  # Stage 2 - shallow
                c.setFillColor(dmg_col)
                c.ellipse(x+col_w/2-12, skin_y+16, x+col_w/2+12, skin_y+32, fill=1, stroke=0)
            elif i == 2:  # Stage 3
                c.setFillColor(dmg_col)
                c.ellipse(x+col_w/2-12, skin_y+4, x+col_w/2+12, skin_y+32, fill=1, stroke=0)
            elif i >= 3:  # Stage 4
                c.setFillColor(dmg_col)
                c.ellipse(x+col_w/2-14, skin_y-4, x+col_w/2+14, skin_y+32, fill=1, stroke=0)

            # Title
            c.setFillColor(C_WHITE)
            c.setFont('Helvetica-Bold', 7.5)
            c.drawCentredString(x + (col_w-8)/2, 15 + bh - 16, stage)

            # Description
            c.setFillColor(C_DARK)
            c.setFont('Helvetica', 7)
            for j, ln in enumerate(desc.split('\n')):
                c.drawCentredString(x+(col_w-8)/2, skin_y-14-j*10, ln)


class BoneHealingDiagram(Flowable):
    """Bone healing phases diagram."""
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 2*MARGIN)
        self._height = 140

    def wrap(self, avW, avH):
        self._width = min(self._width, avW)
        return self._width, self._height

    def draw(self):
        c = self.canv
        w = self._width
        phases = [
            ('HAEMATOMA\nFORMATION', 'Hours-Days', colors.HexColor('#C0392B'),
             'Blood fills\nfracture site'),
            ('SOFT CALLUS', 'Days-Weeks', colors.HexColor('#E67E22'),
             'Fibrocartilage\nforms; soft'),
            ('HARD CALLUS', 'Weeks-Months', colors.HexColor('#F1C40F'),
             'Osteoblasts form\nwoven bone'),
            ('REMODELLING', 'Months-Years', colors.HexColor('#27AE60'),
             'Lamellar bone\nreplaces woven'),
        ]
        bw = (w-20)/4 - 6
        for i, (name, timing, col, desc) in enumerate(phases):
            x = 10 + i*(bw+8)
            # main box
            c.setFillColor(col)
            c.roundRect(x, 30, bw, 100, 7, fill=1, stroke=0)
            c.setFillColor(C_WHITE)
            c.setFont('Helvetica-Bold', 8)
            for j, ln in enumerate(name.split('\n')):
                c.drawCentredString(x+bw/2, 115-j*11, ln)
            c.setFont('Helvetica-Oblique', 7)
            c.setFillColor(colors.HexColor('#FDFEFE'))
            c.drawCentredString(x+bw/2, 88, timing)
            c.setFillColor(C_DARK)
            c.setFont('Helvetica', 7)
            for j, ln in enumerate(desc.split('\n')):
                c.drawCentredString(x+bw/2, 66-j*11, ln)
            # arrow
            if i < 3:
                ax = x+bw+2; ay = 80
                c.setStrokeColor(C_GRAY); c.setLineWidth(1.5)
                c.line(ax, ay, ax+6, ay)
                p=c.beginPath()
                p.moveTo(ax+6,ay+3);p.lineTo(ax+6,ay-3);p.lineTo(ax+10,ay);p.close()
                c.setFillColor(C_GRAY); c.drawPath(p,fill=1,stroke=0)


class ScarManagementAlgorithm(Flowable):
    """Scar management flowchart."""
    def __init__(self, width=None):
        super().__init__()
        self._width = width or (PAGE_W - 2*MARGIN)
        self._height = 300

    def _rbox(self, c, x, y, w, h, text, bg, fg=C_WHITE, fs=8):
        c.setFillColor(bg); c.roundRect(x,y,w,h,5,fill=1,stroke=0)
        c.setFillColor(fg); c.setFont('Helvetica-Bold',fs)
        lines = text.split('\n'); total = len(lines)*(fs+2)
        sy = y+h/2+total/2-fs
        for i,ln in enumerate(lines):
            c.drawCentredString(x+w/2, sy-i*(fs+2), ln)

    def _arr(self, c, x1,y1,x2,y2, col=None):
        col = col or C_DARK
        c.setStrokeColor(col); c.setLineWidth(1.2); c.line(x1,y1,x2,y2)
        ang=math.atan2(y2-y1,x2-x1); sz=6
        ax=x2-sz*math.cos(ang-0.4); ay=y2-sz*math.sin(ang-0.4)
        bx=x2-sz*math.cos(ang+0.4); by=y2-sz*math.sin(ang+0.4)
        c.setFillColor(col); p=c.beginPath()
        p.moveTo(x2,y2);p.lineTo(ax,ay);p.lineTo(bx,by);p.close()
        c.drawPath(p,fill=1,stroke=0)

    def wrap(self, avW, avH):
        self._width = min(self._width, avW)
        return self._width, self._height

    def draw(self):
        c = self.canv
        w = self._width
        cx = w/2
        bw = 130; bh = 30

        y0 = self._height - 15
        # Identify scar
        self._rbox(c, cx-75, y0-bh, 150, bh, 'IDENTIFY SCAR TYPE', C_DARK)
        self._arr(c, cx, y0-bh, cx, y0-bh-20)

        # Two types
        y1 = y0-bh-20-bh-5
        self._rbox(c, 20, y1, 130, bh, 'HYPERTROPHIC SCAR\n(stays in boundary)', colors.HexColor('#E67E22'))
        self._rbox(c, w-150, y1, 130, bh, 'KELOID SCAR\n(grows beyond boundary)', C_PRIMARY)
        self._arr(c, cx, y0-bh-20, 85, y1+bh, colors.HexColor('#E67E22'))
        self._arr(c, cx, y0-bh-20, w-85, y1+bh, C_PRIMARY)

        # Hypertrophic treatment steps
        y2 = y1-50
        self._rbox(c, 10, y2, 150, bh, '1st: Silicone gel/sheeting\n(2+ months)', colors.HexColor('#FAD7A0'), fg=C_DARK)
        self._arr(c, 85, y1, 85, y2+bh, colors.HexColor('#E67E22'))

        y3 = y2-50
        self._rbox(c, 10, y3, 150, bh, '2nd: Intralesional\ncorticosteroids', colors.HexColor('#F0B27A'), fg=C_DARK)
        self._arr(c, 85, y2, 85, y3+bh, colors.HexColor('#E67E22'))

        y4 = y3-50
        self._rbox(c, 10, y4, 150, bh, '3rd: PDL / Fractional\nLaser Therapy', colors.HexColor('#E67E22'))
        self._arr(c, 85, y3, 85, y4+bh, colors.HexColor('#E67E22'))

        # Keloid treatment steps
        k2 = y1-50
        self._rbox(c, w-160, k2, 150, bh, '1st: Intralesional\ncorticosteroids', colors.HexColor('#F1948A'), fg=C_DARK)
        self._arr(c, w-85, y1, w-85, k2+bh, C_PRIMARY)

        k3 = k2-50
        self._rbox(c, w-160, k3, 150, bh, '2nd: 5-FU +\ncorticosteroids', colors.HexColor('#E74C3C'))
        self._arr(c, w-85, k2, w-85, k3+bh, C_PRIMARY)

        k4 = k3-50
        self._rbox(c, w-160, k4, 150, bh, '3rd: Laser then\nSurgical excision', C_PRIMARY)
        self._arr(c, w-85, k3, w-85, k4+bh, C_PRIMARY)


# ─── Build PDF Content ───────────────────────────────────────────────────────

def build_pdf():
    path = '/home/daytona/workspace/wound-healing/Wound_Healing_Study_Guide.pdf'
    doc = SimpleDocTemplate(
        path, pagesize=A4,
        leftMargin=MARGIN, rightMargin=MARGIN,
        topMargin=MARGIN, bottomMargin=MARGIN,
        title='Wound Healing & Tissue Repair - Easy Study Guide'
    )

    story = []

    # ── COVER PAGE ──────────────────────────────────────────────────────────
    class CoverPage(Flowable):
        def __init__(self):
            super().__init__()
            self._width = PAGE_W - 2*MARGIN
            self._height = PAGE_H - 2*MARGIN

        def wrap(self, avW, avH):
            return self._width, self._height

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

            # Background gradient simulation
            c.setFillColor(C_DARK)
            c.rect(0, 0, w, h, fill=1, stroke=0)

            # Decorative circles
            c.setFillColor(colors.HexColor('#2C3E50'))
            c.circle(w*0.85, h*0.85, 80, fill=1, stroke=0)
            c.circle(w*0.1, h*0.15, 60, fill=1, stroke=0)
            c.setFillColor(colors.HexColor('#3D566E'))
            c.circle(w*0.9, h*0.2, 40, fill=1, stroke=0)

            # Red accent bar
            c.setFillColor(C_PRIMARY)
            c.rect(0, h*0.45, w, 5, fill=1, stroke=0)

            # Chapter label
            c.setFillColor(C_SEC)
            c.setFont('Helvetica-Bold', 13)
            c.drawCentredString(w/2, h*0.82, 'CHAPTER 3')

            # Main title
            c.setFillColor(C_WHITE)
            c.setFont('Helvetica-Bold', 32)
            c.drawCentredString(w/2, h*0.72, 'WOUND HEALING')
            c.setFont('Helvetica-Bold', 22)
            c.drawCentredString(w/2, h*0.64, '& TISSUE REPAIR')

            # Subtitle
            c.setFillColor(colors.HexColor('#BDC3C7'))
            c.setFont('Helvetica', 13)
            c.drawCentredString(w/2, h*0.54, 'A Complete Easy-to-Understand Study Guide')
            c.drawCentredString(w/2, h*0.49, 'with Diagrams, Flowcharts & Key Points')

            # Features boxes
            features = ['Phases of Healing', 'Coagulation Cascade',
                        'Wound Classification', 'Scar Management',
                        'Chronic Wounds', 'Wound Management']
            for i, feat in enumerate(features):
                row = i // 3; col = i % 3
                fx = 30 + col * (w-60)/3
                fy = h*0.35 - row*35
                c.setFillColor(colors.HexColor('#2980B9'))
                c.roundRect(fx, fy, (w-80)/3, 28, 5, fill=1, stroke=0)
                c.setFillColor(C_WHITE)
                c.setFont('Helvetica-Bold', 8)
                c.drawCentredString(fx + (w-80)/6, fy+10, feat)

            # Bottom bar
            c.setFillColor(C_PRIMARY)
            c.rect(0, 0, w, 35, fill=1, stroke=0)
            c.setFillColor(C_WHITE)
            c.setFont('Helvetica', 10)
            c.drawCentredString(w/2, 13, 'Surgery / Wound Care / Plastic Surgery | Medical Study Resource')

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

    # ── PAGE 1: INTRODUCTION & PHASES ──────────────────────────────────────
    story.append(SectionBanner('1. WHAT IS WOUND HEALING?', C_DARK))
    story.append(Spacer(1, 8))
    story.append(Paragraph(
        'Wound healing is the body\'s natural process of repairing damaged tissue after injury. '
        'Think of it like fixing a torn piece of cloth - it goes through organized steps to restore the skin. '
        'In adults, healing usually results in a <b>scar</b>. In babies (fetal tissue), healing can occur '
        '<b>without any scar</b> - which is why scientists are studying this for regenerative medicine.',
        BODY))
    story.append(Spacer(1, 6))

    story.append(ColorBox(
        'KEY CONCEPT: The 4 Phases of Normal Wound Healing',
        [
            'Phase 1 - HAEMOSTASIS (0-30 min): Stop the bleeding',
            'Phase 2 - INFLAMMATION (Day 1-5): Clean the wound',
            'Phase 3 - PROLIFERATION (Day 3 - 3 weeks): Rebuild the tissue',
            'Phase 4 - REMODELLING (3 weeks - 2 years): Strengthen the scar',
            '',
            'IMPORTANT: These phases OVERLAP - they do not happen one by one!',
        ],
        bg=C_BLUE_LT, title_color=C_ACCENT
    ))
    story.append(Spacer(1, 10))

    # Phases diagram
    story.append(Paragraph('DIAGRAM 1: The 4 Phases of Wound Healing', H2))
    story.append(WoundHealingPhaseDiagram())
    story.append(Spacer(1, 6))

    # Phase details table
    story.append(Paragraph('DETAILED BREAKDOWN OF EACH PHASE', H2))

    phase_data = [
        ['PHASE', 'TIMING', 'MAIN CELLS', 'WHAT HAPPENS', 'SIGNS'],
        ['1. HAEMOSTASIS\n(Stop Bleeding)', '0-30 min', 'Platelets', 
         'Vessels tighten\nPlatelet plug forms\nBlood clot made', 'Bleeding stops'],
        ['2. INFLAMMATION\n(Clean Wound)', 'Day 1-5',
         'Neutrophils (day1-2)\nMacrophages (day2-3)',
         'Kill bacteria\nRemove dead tissue\nRelease growth factors',
         'Redness (rubor)\nSwelling (tumor)\nHeat (calor)\nPain (dolor)'],
        ['3. PROLIFERATION\n(Rebuild)', 'Day 3 -\n3 weeks', 'Fibroblasts',
         'Make new collagen\nNew blood vessels (angiogenesis)\nRe-epithelialisation',
         'Pink granulation\ntissue visible'],
        ['4. REMODELLING\n(Strengthen)', '3wks -\n2 years', 'Fibroblasts\nCollagen',
         'Type III -> Type I collagen\nCollagen becomes stronger\nWound contracts',
         'Scar matures\nFades, flattens\n80% strength'],
    ]

    pt = Table(phase_data, colWidths=[2.8*cm, 1.8*cm, 3.2*cm, 4.2*cm, 3.0*cm])
    pt.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), C_DARK),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8),
        ('BACKGROUND', (0,1), (0,1), colors.HexColor('#FADBD8')),
        ('BACKGROUND', (0,2), (0,2), colors.HexColor('#FAD7A0')),
        ('BACKGROUND', (0,3), (0,3), colors.HexColor('#AED6F1')),
        ('BACKGROUND', (0,4), (0,4), colors.HexColor('#A9DFBF')),
        ('ROWBACKGROUNDS', (1,1), (-1,-1), [colors.HexColor('#FFF9F9'), colors.white]),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('ALIGN', (0,0), (-1,-1), 'CENTER'),
        ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
        ('TOPPADDING', (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ]))
    story.append(pt)
    story.append(PageBreak())

    # ── PAGE 2: HAEMOSTASIS DETAIL ─────────────────────────────────────────
    story.append(SectionBanner('2. HAEMOSTASIS IN DETAIL - STOPPING THE BLEED', C_PRIMARY))
    story.append(Spacer(1, 8))
    story.append(Paragraph(
        'When you injure a blood vessel, the body immediately triggers a series of steps to stop bleeding. '
        'Think of it like a multi-step alarm system that gets activated.',
        BODY))
    story.append(Spacer(1, 6))

    story.append(Paragraph('FLOWCHART 2: The Coagulation Cascade (Simplified)', H2))
    story.append(CoagulationCascadeDiagram())
    story.append(Spacer(1, 8))

    story.append(ColorBox(
        'TWO PATHWAYS TO STOP BLEEDING',
        [
            'INTRINSIC PATHWAY (Contact Activation):',
            '  - Triggered when blood contacts abnormal surfaces (e.g., damaged vessel walls)',
            '  - Factors: XII -> XI -> IX -> VIII -> X',
            '',
            'EXTRINSIC PATHWAY (Tissue Damage):',
            '  - Triggered when tissue is injured and releases Tissue Factor (TF)',
            '  - Factors: VII + Tissue Factor -> X',
            '',
            'COMMON PATHWAY (Both join here):',
            '  - Factor X -> Xa -> Prothrombin (II) -> Thrombin (IIa)',
            '  - Thrombin converts Fibrinogen -> Fibrin -> BLOOD CLOT',
            '  - Factor XIII cross-links fibrin to make it stable',
        ],
        bg=C_RED_LT, title_color=C_PRIMARY
    ))
    story.append(Spacer(1, 8))

    story.append(Paragraph('ROLE OF PLATELETS', H2))
    platelet_data = [
        ['STEP', 'WHAT HAPPENS', 'WHY IT MATTERS'],
        ['1. Adhesion', 'Platelets stick to exposed collagen\nunder damaged vessel', 'First responders to injury'],
        ['2. Activation', 'Platelets release granules with\ngrowth factors (TGF-β, PDGF, VEGF)', 'Signals other cells to start healing'],
        ['3. Aggregation', 'Platelets clump together\nto form a "platelet plug"', 'Physical barrier to stop blood loss'],
        ['4. Amplification', 'Coagulation cascade triggered\nFibrin clot forms around plug', 'Creates stable, permanent clot'],
    ]
    pt2 = Table(platelet_data, colWidths=[3*cm, 6*cm, 5*cm])
    pt2.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), C_PRIMARY),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8.5),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#FFF5F5'), C_WHITE]),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('ALIGN', (0,0), (0,-1), 'CENTER'),
        ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
        ('TOPPADDING', (0,0), (-1,-1), 6),
        ('BOTTOMPADDING', (0,0), (-1,-1), 6),
    ]))
    story.append(pt2)
    story.append(PageBreak())

    # ── PAGE 3: WOUND TYPES ─────────────────────────────────────────────────
    story.append(SectionBanner('3. TYPES OF WOUND HEALING', colors.HexColor('#27AE60')))
    story.append(Spacer(1, 8))
    story.append(Paragraph(
        'Not all wounds heal the same way. Depending on how the wound is managed and '
        'its condition, healing can follow one of three pathways:',
        BODY))
    story.append(Spacer(1, 6))

    story.append(Paragraph('FLOWCHART 3: Types of Wound Healing', H2))
    story.append(WoundTypesFlowchart())
    story.append(Spacer(1, 8))

    heal_types = [
        ['TYPE', 'ALSO CALLED', 'HOW IT HEALS', 'EXAMPLES', 'OUTCOME'],
        ['PRIMARY', '1st Intention\nHealing by closure',
         'Wound edges brought\ntogether (sutured/stapled)\nDirectly approximated',
         'Surgical incisions\nClean cuts\nLacerations', 'Best cosmetic result\nMinimal scar\nFastest'],
        ['SECONDARY', '2nd Intention\nOpen healing',
         'Wound left open\nHeals by granulation\nContracts & re-epithelialises',
         'Infected wounds\nPressure ulcers\nAbscesses', 'More scarring\nSlower\nMore contraction'],
        ['TERTIARY', 'Delayed Primary\n3rd Intention',
         'Initially left open\nCleaned/debrided\nThen closed later',
         'Contaminated wounds\nBite wounds\nGunshot wounds', 'Intermediate\nControlled infection\nGood result'],
    ]
    ht = Table(heal_types, colWidths=[2.5*cm, 3*cm, 4*cm, 3.5*cm, 3*cm])
    ht.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1E8449')),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8),
        ('ROWBACKGROUNDS', (0,1), (-1,-1),
         [colors.HexColor('#EAFAF1'), colors.HexColor('#D5F5E3'), colors.HexColor('#EAFAF1')]),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('ALIGN', (0,0), (0,-1), 'CENTER'),
        ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
        ('TOPPADDING', (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ]))
    story.append(ht)
    story.append(PageBreak())

    # ── PAGE 4: WOUND CLASSIFICATION ────────────────────────────────────────
    story.append(SectionBanner('4. CLASSIFICATION OF WOUNDS', colors.HexColor('#8E44AD')))
    story.append(Spacer(1, 8))
    story.append(Paragraph(
        'Wounds are classified in many ways. The most widely used system is the '
        '<b>US Centers for Disease Control (CDC) Classification</b> which divides wounds '
        'into 4 classes based on how contaminated they are.',
        BODY))
    story.append(Spacer(1, 6))

    story.append(Paragraph('DIAGRAM 4: CDC Wound Classification (SSI Risk)', H2))
    story.append(WoundClassificationTable())
    story.append(Spacer(1, 10))

    story.append(Paragraph('OTHER WAYS TO CLASSIFY WOUNDS', H2))
    class_data = [
        ['CLASSIFICATION BY...', 'CATEGORIES', 'EXAMPLES'],
        ['AETIOLOGY\n(What caused it?)',
         'Clean, Surgical\nShearing/Degloving\nCrush, Blast\nBurn, Bite',
         'Knife cut = clean\nCar accident = crush\nFire = burn'],
        ['DEPTH\n(How deep?)',
         'Epidermal (skin surface)\nDermal (into skin layers)\nFull thickness (through all layers)',
         'Graze = epidermal\nDeep cut = dermal\nPressure sore = full thickness'],
        ['CONTAMINATION\n(How dirty?)',
         'Clean\nClean-contaminated\nContaminated\nDirty',
         'Surgical wound = clean\nOld infected wound = dirty'],
        ['COMPLEXITY',
         'Simple\nComplex (with:\ninfection, necrosis,\ncompartment syndrome)',
         'Paper cut = simple\nGunshot wound = complex'],
    ]
    ct = Table(class_data, colWidths=[4*cm, 5.5*cm, 6.5*cm])
    ct.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#6C3483')),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8.5),
        ('ROWBACKGROUNDS', (0,1), (-1,-1),
         [colors.HexColor('#F4ECF7'), colors.HexColor('#E8DAEF'),
          colors.HexColor('#F4ECF7'), colors.HexColor('#E8DAEF')]),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 6),
        ('BOTTOMPADDING', (0,0), (-1,-1), 6),
    ]))
    story.append(ct)
    story.append(PageBreak())

    # ── PAGE 5: ABNORMAL HEALING ─────────────────────────────────────────────
    story.append(SectionBanner('5. WHEN HEALING GOES WRONG (Abnormal Wound Healing)', C_PRIMARY))
    story.append(Spacer(1, 8))
    story.append(Paragraph(
        'Sometimes wounds fail to heal properly. This can be due to factors at the wound itself (local) '
        'or throughout the whole body (systemic). Understanding these factors helps us prevent poor healing.',
        BODY))
    story.append(Spacer(1, 6))

    story.append(Paragraph('FLOWCHART 5: Factors Affecting Wound Healing', H2))
    story.append(AbnormalWoundFlowchart())
    story.append(Spacer(1, 8))

    story.append(Paragraph('QUICK MEMORY TABLE: Factors That Impair Healing', H2))
    factors_data = [
        ['LOCAL FACTORS (at the wound)', '', 'SYSTEMIC FACTORS (whole body)', ''],
        ['Factor', 'Why it\'s bad', 'Factor', 'Why it\'s bad'],
        ['Skin tension', 'Pulls edges apart', 'Old age', 'Slower cell repair'],
        ['Hypoxia', 'Cells need oxygen to heal', 'Obesity', 'Poor blood supply to tissue'],
        ['Vascular disease', 'Less blood = less nutrients', 'Malnutrition', 'No protein for new tissue'],
        ['Infection', 'Bacteria destroy tissue', 'Smoking', 'Reduces oxygen in blood'],
        ['Foreign bodies', 'Ongoing inflammation', 'Diabetes', 'Nerve/blood vessel damage'],
        ['Radiation', 'Damages blood vessels', 'Steroids', 'Suppress inflammation needed for healing'],
        ['Haematoma', 'Source of infection', 'Chemotherapy', 'Kills fast-dividing repair cells'],
    ]
    ft = Table(factors_data, colWidths=[4*cm, 4.5*cm, 4*cm, 4.5*cm])
    ft.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (1,0), colors.HexColor('#C0392B')),
        ('BACKGROUND', (2,0), (3,0), colors.HexColor('#2980B9')),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('BACKGROUND', (0,1), (1,1), colors.HexColor('#E74C3C')),
        ('BACKGROUND', (2,1), (3,1), colors.HexColor('#3498DB')),
        ('TEXTCOLOR', (0,1), (-1,1), C_WHITE),
        ('SPAN', (0,0), (1,0)),
        ('SPAN', (2,0), (3,0)),
        ('FONTNAME', (0,0), (-1,1), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8.5),
        ('ROWBACKGROUNDS', (0,2), (-1,-1), [colors.HexColor('#FEF9E7'), C_WHITE]),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('ALIGN', (0,0), (-1,-1), 'CENTER'),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ]))
    story.append(ft)
    story.append(PageBreak())

    # ── PAGE 6: SCAR TYPES ──────────────────────────────────────────────────
    story.append(SectionBanner('6. TYPES OF SCARS', colors.HexColor('#E67E22')))
    story.append(Spacer(1, 8))
    story.append(Paragraph(
        'When wound healing is abnormal or excessive, it can result in different types of abnormal scars. '
        'The two main problem scars are <b>hypertrophic scars</b> and <b>keloid scars</b>.',
        BODY))
    story.append(Spacer(1, 6))

    story.append(Paragraph('DIAGRAM 6: Comparison of Scar Types', H2))
    story.append(ScarTypeDiagram())
    story.append(Spacer(1, 10))

    scar_compare = [
        ['FEATURE', 'NORMAL SCAR', 'HYPERTROPHIC SCAR', 'KELOID SCAR'],
        ['Boundary', 'Within wound', 'Within wound', 'EXTENDS BEYOND wound'],
        ['Regression', 'Yes - fades', 'Yes - regresses', 'NO - does not regress'],
        ['Collagen', 'Organised, parallel', 'Disorganised, nodular', 'Very disorganised'],
        ['Common areas', 'Any wound', 'High tension areas\nDeep burns', 'Chest, shoulders\nEarlobes, jaw'],
        ['Risk factors', 'Normal healing', 'Wound tension\nDeep burns', 'Darker skin\nGenetic predisposition'],
        ['Treatment', 'Not needed', 'Silicone + steroids\nLaser if needed', 'Difficult!\nSteroids + surgery +\n5-FU + laser'],
    ]
    st2 = Table(scar_compare, colWidths=[3.5*cm, 3.5*cm, 4.2*cm, 4.8*cm])
    st2.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), C_DARK),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('BACKGROUND', (0,1), (0,-1), colors.HexColor('#F0F0F0')),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8.5),
        ('ROWBACKGROUNDS', (1,1), (-1,-1),
         [C_WHITE, colors.HexColor('#FEF9E7'), C_WHITE, colors.HexColor('#FEF9E7'),
          C_WHITE, colors.HexColor('#FEF9E7')]),
        ('BACKGROUND', (3,1), (3,-1), colors.HexColor('#FEF5F5')),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('ALIGN', (0,0), (-1,-1), 'CENTER'),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ]))
    story.append(st2)
    story.append(PageBreak())

    # ── PAGE 7: SCAR MANAGEMENT ─────────────────────────────────────────────
    story.append(SectionBanner('7. SCAR MANAGEMENT ALGORITHM', colors.HexColor('#8E44AD')))
    story.append(Spacer(1, 8))
    story.append(Paragraph(
        'Managing scars follows a step-up approach - start simple, escalate if needed. '
        'Prevention is always better than treatment!',
        BODY))
    story.append(Spacer(1, 6))

    story.append(Paragraph('FLOWCHART 7: Scar Management Step-by-Step', H2))
    story.append(ScarManagementAlgorithm())
    story.append(Spacer(1, 8))

    story.append(ColorBox(
        'REMEMBER: Prevention is the BEST treatment!',
        [
            '1. Plan incisions along natural skin tension lines (Langer lines)',
            '2. Handle tissue gently during surgery',
            '3. Close without tension - use proper suture technique',
            '4. Start silicone gel/sheeting early after healing',
            '5. Protect from sun (UV increases scar pigmentation)',
            '6. Regular massage of the scar after 6 weeks',
        ],
        bg=colors.HexColor('#F9F0FF'), title_color=colors.HexColor('#8E44AD')
    ))
    story.append(PageBreak())

    # ── PAGE 8: WOUND MANAGEMENT ────────────────────────────────────────────
    story.append(SectionBanner('8. WOUND MANAGEMENT - How to Treat a Wound', C_ACCENT))
    story.append(Spacer(1, 8))
    story.append(Paragraph(
        'Wound management follows a systematic approach. Think of it as <b>4 steps: '
        'Prepare → Wound → Closure → Follow-up</b>.',
        BODY))
    story.append(Spacer(1, 6))

    mgmt_data = [
        ['STEP', 'ACTIONS', 'KEY POINTS'],
        ['PREPARATION\n(Before touching wound)',
         '• Antibiotic prophylaxis (if needed)\n• Tetanus prophylaxis\n• Anaesthesia\n• Wound irrigation (wash with saline)',
         'Give tetanus if:\n- Not vaccinated\n- High-risk wound\n- >10 years since booster'],
        ['WOUND CARE\n(At the wound)',
         '• Debridement (remove dead tissue)\n• Explore wound (find all damage)\n• Repair structures (tendons/nerves)\n• Haemostasis (stop any bleeding)',
         'Debridement types:\n- Surgical (scalpel)\n- Mechanical (irrigation)\n- Autolytic (dressings)\n- Enzymatic (enzymes)\n- Biological (maggots!)'],
        ['CLOSURE\n(Closing the wound)',
         '• Skin closure without tension\n• Consider reconstruction options\n• Choose appropriate sutures\n• Consider drains\n• Optimal dressings',
         'Reconstruction ladder:\n1. Direct closure (simplest)\n2. Skin graft\n3. Local flap\n4. Free flap (most complex)'],
        ['FOLLOW-UP\n(After closure)',
         '• Remove sutures/splints at right time\n• Physiotherapy if needed\n• Monitor for complications\n• Scar management plan',
         'Suture removal times:\nFace: 5 days\nLimbs: 10-14 days\nAbdomen: 10 days'],
    ]
    mt = Table(mgmt_data, colWidths=[3.5*cm, 6.5*cm, 6*cm])
    mt.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), C_ACCENT),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8.5),
        ('BACKGROUND', (0,1), (0,-1), colors.HexColor('#D6EAF8')),
        ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
        ('ROWBACKGROUNDS', (1,1), (-1,-1),
         [colors.HexColor('#EBF5FB'), C_WHITE, colors.HexColor('#EBF5FB'), C_WHITE]),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        ('TOPPADDING', (0,0), (-1,-1), 7),
        ('BOTTOMPADDING', (0,0), (-1,-1), 7),
    ]))
    story.append(mt)
    story.append(Spacer(1, 10))

    story.append(Paragraph('TYPES OF DEBRIDEMENT (Removing dead tissue)', H2))
    deb_data = [
        ['TYPE', 'HOW IT WORKS', 'WHEN USED'],
        ['SURGICAL', 'Scalpel/scissors cuts away dead tissue\nuntil healthy bleeding occurs',
         'Any devitalised wound\nFastest method'],
        ['MECHANICAL', 'Irrigation with water/saline\nWet-to-dry dressings',
         'Non-selective\nCan damage healthy tissue too'],
        ['AUTOLYTIC', 'Special dressings (hydrocolloids)\nKeep wound moist\nWound\'s own enzymes digest dead tissue',
         'Clean wounds\nSlow but gentle'],
        ['ENZYMATIC', 'Collagenase or papain-urea enzymes\napplied topically',
         'When surgery not possible'],
        ['BIOLOGICAL', 'Medical-grade maggots (Lucilla sericata)\nEat only dead tissue, release\nantimicrobial substances',
         'Chronic wounds\nWhen other methods fail'],
    ]
    dt = Table(deb_data, colWidths=[3*cm, 6.5*cm, 6.5*cm])
    dt.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), C_DARK),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8.5),
        ('ROWBACKGROUNDS', (0,1), (-1,-1),
         [colors.HexColor('#FDFEFE'), colors.HexColor('#F2F3F4')]),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 6),
        ('BOTTOMPADDING', (0,0), (-1,-1), 6),
    ]))
    story.append(dt)
    story.append(PageBreak())

    # ── PAGE 9: CHRONIC WOUNDS ──────────────────────────────────────────────
    story.append(SectionBanner('9. CHRONIC WOUNDS', colors.HexColor('#922B21')))
    story.append(Spacer(1, 8))
    story.append(Paragraph(
        'Chronic wounds are wounds that <b>fail to progress through normal healing stages</b>. '
        'They are stuck - usually in the inflammatory phase. They often have prolonged inflammation '
        'and persistent infections.',
        BODY))
    story.append(Spacer(1, 6))

    story.append(Paragraph('TYPES OF CHRONIC WOUNDS', H2))
    chronic_data = [
        ['TYPE', 'CAUSE', 'WHERE', 'KEY FEATURE'],
        ['PRESSURE ULCERS\n(Pressure Injuries)', 'Pressure over bony prominence\nCompresses blood vessels',
         'Sacrum, heel,\nischium, malleolus', 'Staged 1-4\nPreventable!'],
        ['VENOUS LEG ULCERS', 'Venous hypertension\nBlood pools in legs\nSkin breaks down',
         'Above medial\nmalleolus (ankle)', 'Irregular edges\nSlopy base\nOedema present'],
        ['ARTERIAL ULCERS', 'Poor arterial blood supply\nIschaemia kills tissue',
         'Tips of toes\nLateral ankle', 'Punched-out look\nPainful\nPale/cold limb'],
        ['DIABETIC ULCERS', 'Neuropathy (can\'t feel pain)\n+ Poor circulation',
         'Pressure points\nof foot', 'Painless!\nDeep\nSlow healing'],
        ['NECROTISING\nFASCIITIS', 'Severe bacterial infection\nStreptococcus (Group A)\nDestroys fascia',
         'Any area\n(limbs common)', 'EMERGENCY!\n"Dishwasher pus"\nRapidly spreading'],
    ]
    cwt = Table(chronic_data, colWidths=[3.5*cm, 4.5*cm, 3.5*cm, 4.5*cm])
    cwt.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#922B21')),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8.5),
        ('ROWBACKGROUNDS', (0,1), (-1,-1),
         [colors.HexColor('#FDEDEC'), C_WHITE, colors.HexColor('#FDEDEC'), C_WHITE, colors.HexColor('#FDEDEC')]),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
        ('TOPPADDING', (0,0), (-1,-1), 6),
        ('BOTTOMPADDING', (0,0), (-1,-1), 6),
    ]))
    story.append(cwt)
    story.append(Spacer(1, 10))

    # Pressure ulcer staging
    story.append(Paragraph('DIAGRAM 9: Pressure Ulcer Staging (US NPIAP System)', H2))
    story.append(PressureUlcerStaging())
    story.append(Spacer(1, 6))

    stage_data = [
        ['STAGE', 'SKIN INVOLVEMENT', 'APPEARANCE', 'TREATMENT'],
        ['Stage 1', 'Intact skin\nRedness only', 'Non-blanchable erythema\nSkin not broken', 'Reposition\nProtective dressing'],
        ['Stage 2', 'Partial thickness\nEpidermis/dermis', 'Shallow open ulcer\nOr intact blister', 'Moist dressings\nRelieve pressure'],
        ['Stage 3', 'Full thickness\nSubcutaneous tissue', 'Deep crater\nFat may be visible', 'Debridement\nAdvanced dressings'],
        ['Stage 4', 'Full thickness\nBone/tendon visible', 'Exposed bone/muscle\nOften with infection', 'Surgery often needed\nReconstruction'],
        ['Unstageable', 'Unknown - covered\nby slough/eschar', 'Can\'t see base\nof wound', 'Debride first\nthen re-stage'],
    ]
    stt = Table(stage_data, colWidths=[2.5*cm, 4*cm, 4.5*cm, 5*cm])
    stt.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#7B241C')),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8.5),
        ('ROWBACKGROUNDS', (0,1), (-1,-1),
         [colors.HexColor('#FFF9F9'), colors.HexColor('#FDEDEC')] * 3),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ]))
    story.append(stt)
    story.append(PageBreak())

    # ── PAGE 10: BONE AND OTHER TISSUES ─────────────────────────────────────
    story.append(SectionBanner('10. HEALING IN OTHER TISSUES', colors.HexColor('#1A5276')))
    story.append(Spacer(1, 8))

    story.append(Paragraph('A. BONE HEALING', H2))
    story.append(Paragraph(
        'Bone heals differently from skin. Most fractures heal through <b>callus formation</b> - '
        'a process called indirect/secondary bone healing. Think of callus as scaffolding '
        'that gradually gets replaced by proper bone.',
        BODY))
    story.append(Spacer(1, 6))
    story.append(BoneHealingDiagram())
    story.append(Spacer(1, 6))

    bone_data = [
        ['PHASE', 'TIMING', 'WHAT FORMS', 'KEY CELLS'],
        ['1. Haematoma', 'Hours-Days', 'Blood clot at fracture site\nBrings stem cells', 'Platelets, Macrophages'],
        ['2. Soft Callus', 'Days-3 weeks', 'Fibrocartilage forms\nSoft, flexible bridge', 'Chondrocytes, Fibroblasts'],
        ['3. Hard Callus', '3-12 weeks', 'Woven bone forms\nFracture more stable', 'Osteoblasts'],
        ['4. Remodelling', 'Months-Years', 'Woven -> Lamellar bone\nNormal anatomy restored', 'Osteoblasts, Osteoclasts'],
    ]
    bt = Table(bone_data, colWidths=[3*cm, 3*cm, 5*cm, 5*cm])
    bt.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1A5276')),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8.5),
        ('ROWBACKGROUNDS', (0,1), (-1,-1),
         [colors.HexColor('#EBF5FB'), C_WHITE, colors.HexColor('#EBF5FB'), C_WHITE]),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 6),
        ('BOTTOMPADDING', (0,0), (-1,-1), 6),
    ]))
    story.append(bt)
    story.append(Spacer(1, 10))

    story.append(Paragraph('B. NERVE HEALING', H2))
    story.append(Paragraph(
        'Peripheral nerves regenerate slowly. The key process is <b>Wallerian degeneration</b> '
        '- where the damaged part breaks down - followed by guided regrowth.',
        BODY))
    nerve_data = [
        ['STAGE', 'WHAT HAPPENS', 'TIMING'],
        ['1. Injury', 'Nerve fibre cut or compressed\nDistal part begins to die (Wallerian degeneration)', 'Immediate'],
        ['2. Degeneration', 'Myelin and axon debris cleared by macrophages\nSchwann cells proliferate', 'Days-Weeks'],
        ['3. Regeneration', 'Axon sprouts grow from proximal stump\nGuided by Schwann cell tubes', 'Weeks-Months'],
        ['4. Recovery', 'Axon reaches target organ\nMyelination occurs\nFunction partially restored', 'Months-Years'],
    ]
    nt = Table(nerve_data, colWidths=[3*cm, 8.5*cm, 4.5*cm])
    nt.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1A5276')),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8.5),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#EBF5FB'), C_WHITE]),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 6),
        ('BOTTOMPADDING', (0,0), (-1,-1), 6),
    ]))
    story.append(nt)
    story.append(Spacer(1, 8))

    story.append(ColorBox(
        'Nerve Regeneration Rate',
        ['Nerves regenerate at approximately 1 mm per day (or about 1 inch per month)',
         'This is why nerve injuries can take months to years to recover',
         'The longer/more proximal the injury, the longer the recovery',
         'Complete recovery is rare - partial function is the usual outcome'],
        bg=colors.HexColor('#EBF5FB'), title_color=colors.HexColor('#1A5276')
    ))
    story.append(PageBreak())

    # ── PAGE 11: ACUTE WOUNDS ───────────────────────────────────────────────
    story.append(SectionBanner('11. SPECIFIC ACUTE WOUNDS', colors.HexColor('#117A65')))
    story.append(Spacer(1, 8))

    story.append(Paragraph('A. BITES', H2))
    bite_data = [
        ['TYPE', 'RISK', 'MANAGEMENT'],
        ['Human bite\n(esp. fist-to-tooth)', 'HIGH - human mouth bacteria\nStreptococcus, Eikenella',
         'Treat as contaminated\nExplore the joint\nIV antibiotics\nDo NOT close primarily'],
        ['Dog/animal bite', 'Moderate - Pasteurella\nRabies risk in endemic areas',
         'Wash thoroughly\nConsider rabies prophylaxis\nAntibiotics\nTetanus if needed'],
    ]
    btt = Table(bite_data, colWidths=[3*cm, 5.5*cm, 7.5*cm])
    btt.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#117A65')),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8.5),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#E9F7EF'), C_WHITE]),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 6),
        ('BOTTOMPADDING', (0,0), (-1,-1), 6),
    ]))
    story.append(btt)
    story.append(Spacer(1, 8))

    story.append(Paragraph('B. DEGLOVING INJURIES', H2))
    story.append(Paragraph(
        'Degloving = the skin and subcutaneous fat is stripped away from the underlying muscle/bone. '
        'Like peeling the skin off a drum.',
        BODY))
    dg_data = [
        ['TYPE', 'DESCRIPTION', 'COMMON CAUSE'],
        ['Open degloving', 'Skin physically stripped off\nRaw muscle/bone visible',
         'Finger caught in machinery\nRing avulsion injuries'],
        ['Closed degloving\n(Morel-Lavallee)', 'Skin sheared but still attached\nHaematoma forms underneath\nSkin may die',
         'Motor vehicle accidents\nFalls onto hard surface'],
    ]
    dgt = Table(dg_data, colWidths=[3.5*cm, 5.5*cm, 7*cm])
    dgt.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#117A65')),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8.5),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#E9F7EF'), C_WHITE]),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 6),
        ('BOTTOMPADDING', (0,0), (-1,-1), 6),
    ]))
    story.append(dgt)
    story.append(Spacer(1, 8))

    story.append(Paragraph('C. ACUTE COMPARTMENT SYNDROME', H2))
    story.append(ColorBox(
        'ACUTE COMPARTMENT SYNDROME - Surgical Emergency!',
        [
            'WHAT: Increased pressure in a closed muscle compartment -> blood cannot get in',
            'CAUSES: Fractures (most common), burns, crush injuries, tight casts',
            'SYMPTOMS (5 Ps):',
            '   1. Pain (out of proportion to injury - hallmark sign!)',
            '   2. Pressure (compartment feels tight/hard)',
            '   3. Paraesthesia (tingling/numbness)',
            '   4. Paresis (weakness of muscles in compartment)',
            '   5. Pallor (pale skin if severely compromised)',
            'DIAGNOSIS: Compartment pressure >30 mmHg (or <30 mmHg below diastolic BP)',
            'TREATMENT: EMERGENCY FASCIOTOMY - cut all compartments open',
            'WARNING: Delaying treatment = irreversible muscle damage = Volkmanns contracture',
        ],
        bg=colors.HexColor('#FDEDEC'), title_color=C_PRIMARY
    ))
    story.append(PageBreak())

    # ── PAGE 12: QUICK REFERENCE / SUMMARY ──────────────────────────────────
    story.append(SectionBanner('12. QUICK REFERENCE SUMMARY', C_DARK))
    story.append(Spacer(1, 8))

    story.append(Paragraph('MASTER SUMMARY TABLE', H2))
    summary_data = [
        ['TOPIC', 'KEY POINTS TO REMEMBER'],
        ['4 Phases of\nWound Healing',
         'Haemostasis (0-30min) -> Inflammation (day1-5) -> Proliferation (day3-3wks) -> Remodelling (3wks-2yrs)'],
        ['Haemostasis',
         'Vessel constriction -> Platelet adhesion -> Platelet activation -> Platelet aggregation -> Coagulation cascade -> Clot'],
        ['Coagulation',
         'Intrinsic (contact) + Extrinsic (tissue factor) -> Common pathway -> Thrombin -> Fibrin -> Stable clot'],
        ['Inflammation Signs',
         'Rubor (redness) + Tumor (swelling) + Calor (heat) + Dolor (pain) = RTCD'],
        ['Types of Healing',
         'Primary (1st intention) = closed wounds; Secondary (2nd) = open wounds; Tertiary (3rd) = delayed closure'],
        ['Wound Classes',
         'Class I (Clean) < Class II (Clean-contaminated) < Class III (Contaminated) < Class IV (Dirty)'],
        ['Abnormal Healing',
         'Local factors: infection, tension, ischaemia | Systemic: DM, obesity, steroids, smoking, age'],
        ['Hypertrophic vs Keloid',
         'Hypertrophic = stays within wound, regresses | Keloid = extends beyond, does NOT regress'],
        ['Scar Treatment',
         'First: Silicone gel/sheeting | Second: Steroids | Third: Laser | Fourth: Surgery'],
        ['Pressure Ulcers',
         'Stage 1: redness | Stage 2: blister/shallow | Stage 3: deep crater | Stage 4: bone exposed'],
        ['Debridement',
         'Surgical > Mechanical > Autolytic > Enzymatic > Biological (maggots)'],
        ['Compartment Syndrome',
         '5 Ps: Pain, Pressure, Paraesthesia, Paresis, Pallor | EMERGENCY = Fasciotomy'],
        ['Tetanus Prone Wounds',
         'Puncture, bite, compound fracture, foreign body, >6hr delay, devitalised tissue'],
        ['Bone Healing',
         'Haematoma -> Soft callus (fibrocartilage) -> Hard callus (woven bone) -> Remodelling (lamellar)'],
        ['Nerve Regeneration',
         'Wallerian degeneration -> Schwann cell proliferation -> Axon regrowth at 1mm/day'],
    ]
    smtable = Table(summary_data, colWidths=[4*cm, 12*cm])
    smtable.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), C_DARK),
        ('TEXTCOLOR', (0,0), (-1,0), C_WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,-1), 8),
        ('ROWBACKGROUNDS', (1,1), (-1,-1),
         [colors.HexColor('#EBF5FB'), colors.HexColor('#FDFEFE')] * 8),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ]))
    story.append(smtable)
    story.append(Spacer(1, 12))

    story.append(ColorBox(
        'EXAM MNEMONICS',
        [
            'RTCD = Rubor, Tumor, Calor, Dolor (signs of inflammation)',
            '5 Ps of Compartment Syndrome = Pain, Pressure, Paraesthesia, Paresis, Pallor',
            'CLEAN wounds = No entry into body cavities + No inflammation',
            'KELOID = K for Kollagen extending beyond boundaries (Keloid grows BEYOND wound)',
            'Nerve regrowth = 1 mm/day = slow as a calendar (months to years for full recovery)',
            'Primary bone healing = requires rigid fixation (ORIF) - callus does NOT form',
        ],
        bg=colors.HexColor('#FEF9E7'), title_color=colors.HexColor('#B7950B')
    ))

    # Build
    doc.build(story)
    print(f'PDF created: {path}')
    return path

if __name__ == '__main__':
    result = build_pdf()
    print(result)
Running Command

cd /home/daytona/workspace/wound-healing && python create_pdf.py 2>&1

Editing File

~/wound-healing/create_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/wound-healing/create_pdf.py'
Running Command

cd /home/daytona/workspace/wound-healing && python create_pdf.py 2>&1

The CoverPage flowable needs fixed dimensions. Let me fix the cover page and build issues:
Editing File

~/wound-healing/create_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/wound-healing/create_pdf.py'
Running Command

cd /home/daytona/workspace/wound-healing && python create_pdf.py 2>&1

retry

The issue is the CoverPage being too large for the frame. I'll rewrite using a cleaner approach - draw the cover directly via a canvas onFirstPage callback, and use proper smaller heights for all custom flowables.
Writing File

~/wound-healing/create_pdf.py

"""
Wound Healing and Tissue Repair - Comprehensive Easy Study Guide PDF
"""
import math
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.units import cm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak
)
from reportlab.platypus.flowables import Flowable
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.pdfgen import canvas as pdfcanvas
from reportlab.lib.utils import ImageReader
import io

PAGE_W, PAGE_H = A4
MARGIN = 1.8 * cm

# ── Colours ──────────────────────────────────────────────────────────────────
C_DARK   = colors.HexColor('#1A1A2E')
C_RED    = colors.HexColor('#C0392B')
C_AMBER  = colors.HexColor('#E67E22')
C_BLUE   = colors.HexColor('#2980B9')
C_GREEN  = colors.HexColor('#1E8449')
C_PURPLE = colors.HexColor('#6C3483')
C_TEAL   = colors.HexColor('#117A65')
C_NAVY   = colors.HexColor('#1A5276')
C_WHITE  = colors.white
C_LGRAY  = colors.HexColor('#F2F3F4')
C_LYELL  = colors.HexColor('#FEF9E7')
C_LRED   = colors.HexColor('#FDEDEC')
C_LBLUE  = colors.HexColor('#EBF5FB')
C_LGREEN = colors.HexColor('#EAFAF1')
C_LPUR   = colors.HexColor('#F4ECF7')
C_GRAY   = colors.HexColor('#7F8C8D')

# ── Styles ────────────────────────────────────────────────────────────────────
def S(name, **kw):
    return ParagraphStyle(name, **kw)

H1 = S('H1', fontName='Helvetica-Bold', fontSize=15, textColor=C_RED,
        spaceBefore=10, spaceAfter=5)
H2 = S('H2', fontName='Helvetica-Bold', fontSize=12, textColor=C_DARK,
        spaceBefore=8, spaceAfter=4)
H3 = S('H3', fontName='Helvetica-Bold', fontSize=10, textColor=C_BLUE,
        spaceBefore=6, spaceAfter=3)
BODY = S('BODY', fontName='Helvetica', fontSize=9.5, textColor=C_DARK,
         leading=14, spaceAfter=5, alignment=TA_JUSTIFY)
NOTE = S('NOTE', fontName='Helvetica-Oblique', fontSize=8.5, textColor=C_GRAY,
         leading=12, spaceAfter=4)

# ── Helper: draw arrow ────────────────────────────────────────────────────────
def draw_arrow(c, x1, y1, x2, y2, col=None, lw=1.2):
    col = col or C_DARK
    c.setStrokeColor(col)
    c.setLineWidth(lw)
    c.line(x1, y1, x2, y2)
    angle = math.atan2(y2 - y1, x2 - x1)
    sz = 5
    ax = x2 - sz * math.cos(angle - 0.4)
    ay = y2 - sz * math.sin(angle - 0.4)
    bx = x2 - sz * math.cos(angle + 0.4)
    by = y2 - sz * math.sin(angle + 0.4)
    c.setFillColor(col)
    p = c.beginPath()
    p.moveTo(x2, y2); p.lineTo(ax, ay); p.lineTo(bx, by); p.close()
    c.drawPath(p, fill=1, stroke=0)

# ── Helper: rounded coloured box with title ───────────────────────────────────
def draw_titled_box(c, x, y, w, h, title, body_lines,
                    bg=None, title_col=None, font_size=8.5):
    bg = bg or C_LBLUE
    title_col = title_col or C_BLUE
    c.setFillColor(bg)
    c.roundRect(x, y, w, h, 6, fill=1, stroke=0)
    c.setFillColor(title_col)
    c.roundRect(x, y + h - 18, w, 18, 6, fill=1, stroke=0)
    c.rect(x, y + h - 24, w, 6, fill=1, stroke=0)
    c.setFillColor(C_WHITE)
    c.setFont('Helvetica-Bold', 9)
    c.drawString(x + 8, y + h - 13, title)
    c.setFillColor(C_DARK)
    c.setFont('Helvetica', font_size)
    ty = y + h - 30
    for ln in body_lines:
        c.drawString(x + 8, ty, ln)
        ty -= (font_size + 3)

# ── Helper: centred text in a rect ───────────────────────────────────────────
def rbox(c, x, y, w, h, text, bg, fg=None, fs=8.5, bold=True):
    fg = fg or C_WHITE
    c.setFillColor(bg)
    c.roundRect(x, y, w, h, 5, fill=1, stroke=0)
    c.setFillColor(fg)
    c.setFont('Helvetica-Bold' if bold else 'Helvetica', fs)
    lines = text.split('\n')
    total = len(lines) * (fs + 2)
    sy = y + h / 2 + total / 2 - fs
    for i, ln in enumerate(lines):
        c.drawCentredString(x + w / 2, sy - i * (fs + 2), ln)


# ══════════════════════════════════════════════════════════════════════════════
#  CUSTOM FLOWABLES
# ══════════════════════════════════════════════════════════════════════════════

class Banner(Flowable):
    """Full-width section banner."""
    def __init__(self, text, bg=None, height=30):
        super().__init__()
        self.text = text
        self.bg = bg or C_DARK
        self._height = height

    def wrap(self, avW, avH):
        self._width = avW
        return avW, self._height

    def draw(self):
        c = self.canv
        c.setFillColor(self.bg)
        c.roundRect(0, 0, self._width, self._height, 5, fill=1, stroke=0)
        c.setFillColor(C_WHITE)
        c.setFont('Helvetica-Bold', 13)
        c.drawString(10, 9, self.text)


class InfoBox(Flowable):
    """Coloured info box with title and bullet lines."""
    def __init__(self, title, lines, bg=None, title_col=None):
        super().__init__()
        self.title = title
        self.lines = lines
        self.bg = bg or C_LBLUE
        self.title_col = title_col or C_BLUE
        self._height = 22 + len(lines) * 13 + 8

    def wrap(self, avW, avH):
        self._width = avW
        return avW, self._height

    def draw(self):
        c = self.canv
        w, h = self._width, self._height
        c.setFillColor(self.bg)
        c.roundRect(0, 0, w, h, 6, fill=1, stroke=0)
        c.setFillColor(self.title_col)
        c.roundRect(0, h - 20, w, 20, 6, fill=1, stroke=0)
        c.rect(0, h - 26, w, 6, fill=1, stroke=0)
        c.setFillColor(C_WHITE)
        c.setFont('Helvetica-Bold', 9)
        c.drawString(8, h - 14, self.title)
        c.setFillColor(C_DARK)
        c.setFont('Helvetica', 8.5)
        ty = h - 32
        for ln in self.lines:
            c.drawString(10, ty, ln)
            ty -= 13


# ─────────────────────────────────────────────────────────────────────────────
class PhaseDiagram(Flowable):
    """4-phase wound healing timeline."""
    HEIGHT = 130

    def wrap(self, avW, avH):
        self._width = avW
        return avW, self.HEIGHT

    def draw(self):
        c = self.canv
        w = self._width
        phases = [
            ('1\nHAEMOSTASIS', '0-30 min', C_RED,
             ['Stop bleeding', 'Platelet plug', 'Blood clot forms']),
            ('2\nINFLAMMATION', 'Day 1-5', C_AMBER,
             ['Neutrophils clean', 'Macrophages arrive', 'Growth factors released']),
            ('3\nPROLIFERATION', 'Day 3-3wks', C_BLUE,
             ['Fibroblasts build', 'New collagen made', 'Angiogenesis']),
            ('4\nREMODELLING', '3wks-2yrs', C_GREEN,
             ['Collagen matures', 'Scar strengthens', '80% strength']),
        ]
        n = len(phases)
        gap = 8
        bw = (w - (n + 1) * gap) / n
        bh = 100
        y0 = 15

        for i, (name, timing, col, details) in enumerate(phases):
            x = gap + i * (bw + gap)
            # shadow
            c.setFillColor(colors.HexColor('#CCCCCC'))
            c.roundRect(x + 3, y0 - 3, bw, bh, 7, fill=1, stroke=0)
            # box
            c.setFillColor(col)
            c.roundRect(x, y0, bw, bh, 7, fill=1, stroke=0)
            # phase number / name
            c.setFillColor(C_WHITE)
            c.setFont('Helvetica-Bold', 8)
            for j, ln in enumerate(name.split('\n')):
                c.drawCentredString(x + bw / 2, y0 + bh - 14 - j * 11, ln)
            # timing badge
            c.setFillColor(colors.HexColor('#FFFFFF55'))
            c.roundRect(x + 4, y0 + bh - 36, bw - 8, 14, 3, fill=1, stroke=0)
            c.setFillColor(C_DARK)
            c.setFont('Helvetica-BoldOblique', 7)
            c.drawCentredString(x + bw / 2, y0 + bh - 26, timing)
            # detail lines
            c.setFillColor(C_WHITE)
            c.setFont('Helvetica', 7.5)
            for j, d in enumerate(details):
                c.drawString(x + 6, y0 + bh - 50 - j * 12, '• ' + d)
            # arrow
            if i < n - 1:
                ax = x + bw + gap / 2
                ay = y0 + bh / 2
                draw_arrow(c, ax - 2, ay, ax + 2, ay, C_GRAY, lw=2)

        # Timeline label
        c.setFillColor(C_LGRAY)
        c.rect(0, 0, w, 12, fill=1, stroke=0)
        c.setFillColor(C_DARK)
        c.setFont('Helvetica-Bold', 7)
        c.drawCentredString(w / 2, 3, 'TIME  →  Phases overlap; healing is a continuous process')


# ─────────────────────────────────────────────────────────────────────────────
class CoagDiagram(Flowable):
    """Coagulation cascade flowchart."""
    HEIGHT = 300

    def wrap(self, avW, avH):
        self._width = avW
        return avW, self.HEIGHT

    def draw(self):
        c = self.canv
        w = self._width
        bw, bh = 120, 26
        cx = w / 2

        # ── Title ──
        c.setFillColor(C_DARK)
        c.setFont('Helvetica-Bold', 11)
        c.drawCentredString(cx, self.HEIGHT - 14, 'COAGULATION CASCADE — Simplified Flowchart')

        rows = [self.HEIGHT - 38, self.HEIGHT - 90, self.HEIGHT - 142,
                self.HEIGHT - 194, self.HEIGHT - 246]

        # Intrinsic (left column)
        ix = 10
        rbox(c, ix, rows[0], bw, bh, 'INTRINSIC PATHWAY\n(Contact Activation)', C_RED)
        rbox(c, ix, rows[1], bw, bh, 'XII→XIIa  XI→XIa', colors.HexColor('#E74C3C'))
        rbox(c, ix, rows[2], bw, bh, 'IX→IXa\n(+ Factor VIII)', colors.HexColor('#E74C3C'))
        draw_arrow(c, ix + bw/2, rows[0], ix + bw/2, rows[1] + bh, C_RED)
        draw_arrow(c, ix + bw/2, rows[1], ix + bw/2, rows[2] + bh, C_RED)

        # Extrinsic (right column)
        ex = w - bw - 10
        rbox(c, ex, rows[0], bw, bh, 'EXTRINSIC PATHWAY\n(Tissue Damage)', C_BLUE)
        rbox(c, ex, rows[1], bw, bh, 'Tissue Factor\n+ VII → VIIa', colors.HexColor('#3498DB'))
        rbox(c, ex, rows[2], bw, bh, 'Activates\nFactor X', colors.HexColor('#3498DB'))
        draw_arrow(c, ex + bw/2, rows[0], ex + bw/2, rows[1] + bh, C_BLUE)
        draw_arrow(c, ex + bw/2, rows[1], ex + bw/2, rows[2] + bh, C_BLUE)

        # Common pathway (centre)
        cmx = cx - bw/2
        rbox(c, cmx, rows[2], bw, bh, 'COMMON PATHWAY\nFactor X → Xa', C_PURPLE)
        rbox(c, cmx, rows[3], bw, bh, 'Prothrombin (II)\n→ Thrombin (IIa)', colors.HexColor('#8E44AD'))
        rbox(c, cmx, rows[4], bw, bh, 'Fibrinogen → Fibrin\nStable CLOT (XIII)', C_GREEN)

        # Converging arrows
        draw_arrow(c, ix + bw, rows[2] + bh/2, cmx, rows[2] + bh/2, C_PURPLE)
        draw_arrow(c, ex, rows[2] + bh/2, cmx + bw, rows[2] + bh/2, C_PURPLE)
        draw_arrow(c, cx, rows[2], cx, rows[3] + bh, C_PURPLE)
        draw_arrow(c, cx, rows[3], cx, rows[4] + bh, C_GREEN)

        # Labels
        c.setFillColor(C_GRAY)
        c.setFont('Helvetica-Oblique', 7)
        c.drawCentredString(cx, rows[2] + bh + 4, 'Both pathways converge here')

        # Fibrinolysis note
        c.setFillColor(colors.HexColor('#E8F8F5'))
        c.roundRect(w - 115, rows[4] - 8, 110, 22, 4, fill=1, stroke=0)
        c.setFillColor(C_TEAL)
        c.setFont('Helvetica-Bold', 7.5)
        c.drawString(w - 110, rows[4] + 8, 'FIBRINOLYSIS: Plasmin')
        c.setFont('Helvetica', 7)
        c.drawString(w - 110, rows[4] - 2, 'breaks down clot (tPA/uPA)')


# ─────────────────────────────────────────────────────────────────────────────
class HealingTypesDiagram(Flowable):
    """Flowchart for primary / secondary / tertiary healing."""
    HEIGHT = 260

    def wrap(self, avW, avH):
        self._width = avW
        return avW, self.HEIGHT

    def draw(self):
        c = self.canv
        w = self._width
        cx = w / 2
        bw, bh = 140, 28

        y_start = self.HEIGHT - 20
        # Start node
        rbox(c, cx - 70, y_start - bh, bw, bh, 'WOUND OCCURS', C_DARK)
        draw_arrow(c, cx, y_start - bh, cx, y_start - bh - 16)

        # Decision diamond
        dy = y_start - bh - 16 - 28
        pts = [cx, dy + 28, cx + 55, dy + 14, cx, dy, cx - 55, dy + 14]
        c.setFillColor(colors.HexColor('#F39C12'))
        p = c.beginPath()
        p.moveTo(pts[0], pts[1]); p.lineTo(pts[2], pts[3])
        p.lineTo(pts[4], pts[5]); p.lineTo(pts[6], pts[7]); p.close()
        c.drawPath(p, fill=1, stroke=0)
        c.setFillColor(C_WHITE)
        c.setFont('Helvetica-Bold', 7.5)
        c.drawCentredString(cx, dy + 18, 'Wound edges')
        c.drawCentredString(cx, dy + 9, 'approximated?')

        # YES (left) → Primary
        lx = 20
        ly = dy - 70
        draw_arrow(c, cx - 55, dy + 14, lx + bw/2, ly + bh, C_GREEN)
        c.setFillColor(C_GREEN)
        c.setFont('Helvetica-Bold', 8)
        c.drawString(lx + 20, dy + 2, 'YES')
        rbox(c, lx, ly, bw, bh, 'PRIMARY HEALING\n(1st Intention)', C_GREEN)
        # outcome
        c.setFillColor(C_LGREEN)
        c.roundRect(lx, ly - 40, bw, 36, 4, fill=1, stroke=0)
        c.setFillColor(C_DARK); c.setFont('Helvetica', 7.5)
        c.drawString(lx + 5, ly - 12, '• Edges sutured / closed')
        c.drawString(lx + 5, ly - 24, '• Minimal scar')
        c.drawString(lx + 5, ly - 36, '• Fastest healing')
        draw_arrow(c, lx + bw/2, ly, lx + bw/2, ly - 4, C_GREEN)

        # NO (right) → Secondary
        rx = w - 20 - bw
        ry = dy - 70
        draw_arrow(c, cx + 55, dy + 14, rx + bw/2, ry + bh, C_RED)
        c.setFillColor(C_RED)
        c.setFont('Helvetica-Bold', 8)
        c.drawString(w - 60, dy + 2, 'NO')
        rbox(c, rx, ry, bw, bh, 'SECONDARY HEALING\n(2nd Intention)', C_RED)
        # outcome
        c.setFillColor(C_LRED)
        c.roundRect(rx, ry - 40, bw, 36, 4, fill=1, stroke=0)
        c.setFillColor(C_DARK); c.setFont('Helvetica', 7.5)
        c.drawString(rx + 5, ry - 12, '• Wound left open')
        c.drawString(rx + 5, ry - 24, '• Heals by granulation')
        c.drawString(rx + 5, ry - 36, '• More scarring')
        draw_arrow(c, rx + bw/2, ry, rx + bw/2, ry - 4, C_RED)

        # Tertiary (centre bottom)
        ty_box = dy - 130
        rbox(c, cx - 70, ty_box, bw, bh, 'TERTIARY HEALING\n(Delayed 1st Intention)', C_AMBER)
        draw_arrow(c, cx, dy, cx, ty_box + bh, C_AMBER)
        c.setFillColor(C_LYELL)
        c.roundRect(cx - 70, ty_box - 38, bw, 34, 4, fill=1, stroke=0)
        c.setFillColor(C_DARK); c.setFont('Helvetica', 7.5)
        c.drawString(cx - 65, ty_box - 12, '• Initially left open')
        c.drawString(cx - 65, ty_box - 24, '• Cleaned then closed')
        c.drawString(cx - 65, ty_box - 36, '• Contaminated wounds')


# ─────────────────────────────────────────────────────────────────────────────
class WoundClassDiagram(Flowable):
    """CDC wound classification 4-column visual."""
    HEIGHT = 170

    def wrap(self, avW, avH):
        self._width = avW
        return avW, self.HEIGHT

    def draw(self):
        c = self.canv
        w = self._width
        data = [
            ('CLASS I\nCLEAN', C_GREEN, C_LGREEN,
             ['No inflammation', 'Resp/GI not entered', 'Primarily closed'], 'SSI: 1-5%'),
            ('CLASS II\nCLEAN-CONTAM.', colors.HexColor('#F39C12'), colors.HexColor('#FEF5E7'),
             ['Controlled entry', 'No contamination', 'No major break'], 'SSI: 3-11%'),
            ('CLASS III\nCONTAMINATED', C_AMBER, colors.HexColor('#FDF2E9'),
             ['Fresh open wounds', 'Major sterile break', 'GI spillage'], 'SSI: 10-17%'),
            ('CLASS IV\nDIRTY', C_RED, C_LRED,
             ['Old traumatic wounds', 'Devitalised tissue', 'Existing infection'], 'SSI: >27%'),
        ]
        cw = (w - 20) / 4
        for i, (title, hcol, bcol, lines, ssi) in enumerate(data):
            x = 10 + i * cw
            # header
            c.setFillColor(hcol)
            c.roundRect(x, self.HEIGHT - 40, cw - 6, 36, 5, fill=1, stroke=0)
            c.setFillColor(C_WHITE); c.setFont('Helvetica-Bold', 8)
            for j, ln in enumerate(title.split('\n')):
                c.drawCentredString(x + (cw-6)/2, self.HEIGHT - 18 - j * 11, ln)
            # body
            c.setFillColor(bcol)
            c.roundRect(x, self.HEIGHT - 40 - 90, cw - 6, 88, 4, fill=1, stroke=0)
            c.setFillColor(C_DARK); c.setFont('Helvetica', 7.5)
            for j, ln in enumerate(lines):
                c.drawString(x + 5, self.HEIGHT - 56 - j * 13, '• ' + ln)
            # SSI badge
            c.setFillColor(hcol)
            c.roundRect(x, self.HEIGHT - 40 - 110, cw - 6, 16, 4, fill=1, stroke=0)
            c.setFillColor(C_WHITE); c.setFont('Helvetica-Bold', 8)
            c.drawCentredString(x + (cw-6)/2, self.HEIGHT - 40 - 101, ssi)


# ─────────────────────────────────────────────────────────────────────────────
class AbnormalFlowchart(Flowable):
    """Flowchart: factors causing abnormal wound healing."""
    HEIGHT = 240

    def wrap(self, avW, avH):
        self._width = avW
        return avW, self.HEIGHT

    def draw(self):
        c = self.canv
        w = self._width
        cx = w / 2
        bw, bh = 160, 28

        # Top
        rbox(c, cx - 80, self.HEIGHT - 35, bw, bh, 'WOUND FAILS TO HEAL\nNORMALLY', C_DARK)
        draw_arrow(c, cx, self.HEIGHT - 35, cx, self.HEIGHT - 35 - 18)

        # Two branches
        branch_y = self.HEIGHT - 35 - 18 - bh - 5
        rbox(c, 10, branch_y, 150, bh, 'LOCAL FACTORS', C_RED)
        rbox(c, w - 160, branch_y, 150, bh, 'SYSTEMIC FACTORS', C_BLUE)
        draw_arrow(c, cx, self.HEIGHT - 35 - 18, 85, branch_y + bh, C_RED)
        draw_arrow(c, cx, self.HEIGHT - 35 - 18, w - 85, branch_y + bh, C_BLUE)

        local = ['Skin tension', 'Hypoxia / ischaemia', 'Vascular insufficiency',
                 'Infection', 'Foreign bodies', 'Radiotherapy', 'Haematoma']
        c.setFillColor(C_LRED)
        c.roundRect(10, branch_y - 105, 150, 103, 5, fill=1, stroke=0)
        c.setFillColor(C_DARK); c.setFont('Helvetica', 8)
        for i, ln in enumerate(local):
            c.drawString(16, branch_y - 15 - i * 13, '• ' + ln)

        systemic = ['Old age', 'Obesity / Malnutrition', 'Smoking',
                    'Diabetes mellitus', 'Immunocompromised', 'Steroids', 'Chemotherapy']
        c.setFillColor(C_LBLUE)
        c.roundRect(w - 160, branch_y - 105, 150, 103, 5, fill=1, stroke=0)
        c.setFillColor(C_DARK); c.setFont('Helvetica', 8)
        for i, ln in enumerate(systemic):
            c.drawString(w - 155, branch_y - 15 - i * 13, '• ' + ln)

        # Result
        rbox(c, cx - 90, 10, 180, bh, 'CHRONIC WOUND /\nHYPERTROPHIC / KELOID SCAR', C_PURPLE)
        draw_arrow(c, 85, branch_y, cx, 10 + bh, C_RED)
        draw_arrow(c, w - 85, branch_y, cx, 10 + bh, C_BLUE)


# ─────────────────────────────────────────────────────────────────────────────
class ScarDiagram(Flowable):
    """Visual comparison of normal / hypertrophic / keloid scars."""
    HEIGHT = 155

    def wrap(self, avW, avH):
        self._width = avW
        return avW, self.HEIGHT

    def draw(self):
        c = self.canv
        w = self._width
        types = [
            ('NORMAL SCAR', C_GREEN,
             ['Within wound boundary', 'Flattens over time', 'Fades, no recurrence']),
            ('HYPERTROPHIC SCAR', C_AMBER,
             ['Raised but within wound', 'Red/itchy initially', 'Regresses over time']),
            ('KELOID SCAR', C_RED,
             ['Extends BEYOND wound!', 'Does NOT regress', 'Dark skin predisposed']),
        ]
        cw = (w - 20) / 3
        for i, (name, col, details) in enumerate(types):
            x = 10 + i * cw
            skin_y = self.HEIGHT - 10

            # Skin cross-section background
            c.setFillColor(colors.HexColor('#F5CBA7'))
            c.rect(x + 4, skin_y - 55, cw - 12, 48, fill=1, stroke=0)

            # Scar bulge
            wound_cx = x + (cw - 12) / 2 + 4
            c.setFillColor(col)
            if i == 0:
                c.rect(wound_cx - 2, skin_y - 55, 4, 40, fill=1, stroke=0)
            elif i == 1:
                c.ellipse(wound_cx - 8, skin_y - 55, wound_cx + 8, skin_y - 14,
                          fill=1, stroke=0)
            else:
                c.ellipse(wound_cx - 18, skin_y - 58, wound_cx + 18, skin_y - 10,
                          fill=1, stroke=0)

            # Header
            c.setFillColor(col)
            c.roundRect(x + 4, skin_y - 10, cw - 12, 12, 3, fill=1, stroke=0)
            c.setFillColor(C_WHITE); c.setFont('Helvetica-Bold', 7.5)
            c.drawCentredString(wound_cx, skin_y - 3, name)

            # Detail bullets
            c.setFillColor(colors.HexColor('#FAFAFA'))
            c.roundRect(x + 4, skin_y - 55 - 60, cw - 12, 58, 4, fill=1, stroke=0)
            c.setFillColor(C_DARK); c.setFont('Helvetica', 7.5)
            for j, d in enumerate(details):
                c.drawString(x + 8, skin_y - 70 - j * 13, '• ' + d)


# ─────────────────────────────────────────────────────────────────────────────
class ScarMgmtFlowchart(Flowable):
    """Scar management algorithm flowchart."""
    HEIGHT = 280

    def wrap(self, avW, avH):
        self._width = avW
        return avW, self.HEIGHT

    def draw(self):
        c = self.canv
        w = self._width
        cx = w / 2
        bw, bh = 130, 26

        # Title
        rbox(c, cx - 75, self.HEIGHT - 30, 150, 26, 'IDENTIFY SCAR TYPE', C_DARK)
        draw_arrow(c, cx, self.HEIGHT - 30, cx, self.HEIGHT - 30 - 16)

        ty = self.HEIGHT - 30 - 16 - bh - 4
        rbox(c, 15, ty, 140, bh, 'HYPERTROPHIC SCAR\n(within boundary)', C_AMBER)
        rbox(c, w - 155, ty, 140, bh, 'KELOID SCAR\n(beyond boundary)', C_RED)
        draw_arrow(c, cx, self.HEIGHT - 30 - 16, 85, ty + bh, C_AMBER)
        draw_arrow(c, cx, self.HEIGHT - 30 - 16, w - 85, ty + bh, C_RED)

        # Hypertrophic steps
        steps_h = [
            ('Silicone gel/sheeting\n(2+ months)', colors.HexColor('#F0B27A')),
            ('Intralesional\ncorticosteroids', colors.HexColor('#E67E22')),
            ('PDL / Fractional\nLaser therapy', colors.HexColor('#CA6F1E')),
            ('Surgical excision\n+ post-op silicone', colors.HexColor('#935116')),
        ]
        hy = ty - 50
        for j, (txt, col) in enumerate(steps_h):
            rbox(c, 10, hy - j * 50, 150, bh, txt, col)
            draw_arrow(c, 85, hy - (j-1)*50 if j>0 else ty, 85, hy - j*50 + bh, C_AMBER)
            c.setFillColor(C_GRAY); c.setFont('Helvetica', 7)
            c.drawString(12, hy - j*50 + bh + 3, f'Step {j+1}')

        # Keloid steps
        steps_k = [
            ('Intralesional\ncorticosteroids', colors.HexColor('#F1948A')),
            ('5-FU + intralesional\ncorticosteroids', colors.HexColor('#E74C3C')),
            ('Fractional / PDL\nLaser therapy', colors.HexColor('#C0392B')),
            ('Surgical excision\n+ radiotherapy', colors.HexColor('#7B241C')),
        ]
        ky = ty - 50
        for j, (txt, col) in enumerate(steps_k):
            rbox(c, w - 160, ky - j * 50, 150, bh, txt, col)
            draw_arrow(c, w - 85, ky - (j-1)*50 if j>0 else ty, w - 85, ky - j*50 + bh, C_RED)
            c.setFillColor(C_GRAY); c.setFont('Helvetica', 7)
            c.drawString(w - 158, ky - j*50 + bh + 3, f'Step {j+1}')


# ─────────────────────────────────────────────────────────────────────────────
class PressureUlcerDiagram(Flowable):
    """Pressure ulcer staging diagram with skin cross-section."""
    HEIGHT = 185

    def wrap(self, avW, avH):
        self._width = avW
        return avW, self.HEIGHT

    def draw(self):
        c = self.canv
        w = self._width
        stages = [
            ('STAGE 1', colors.HexColor('#F9E79F'), C_DARK,
             'Intact skin\nNon-blanchable\nRedness only'),
            ('STAGE 2', colors.HexColor('#FAD7A0'), C_DARK,
             'Partial thickness\nShallow ulcer\nor blister'),
            ('STAGE 3', colors.HexColor('#F0B27A'), C_DARK,
             'Full thickness\nSubcut visible\nDeep crater'),
            ('STAGE 4', colors.HexColor('#E59866'), C_WHITE,
             'Bone/tendon\nvisible\nSurgery needed'),
            ('UNSTAGEABLE', colors.HexColor('#CA6F1E'), C_WHITE,
             'Covered by\nslough/eschar\nDebride first'),
        ]
        cw = (w - 20) / 5
        for i, (stage, col, fg, desc) in enumerate(stages):
            x = 10 + i * cw
            bh = 160

            # Skin illustration
            skin_top = self.HEIGHT - 30
            c.setFillColor(colors.HexColor('#F5CBA7'))  # epidermis
            c.rect(x + 3, skin_top - 18, cw - 10, 16, fill=1, stroke=0)
            c.setFillColor(colors.HexColor('#FADBD8'))  # dermis
            c.rect(x + 3, skin_top - 34, cw - 10, 16, fill=1, stroke=0)
            c.setFillColor(colors.HexColor('#FDEBD0'))  # subcutaneous
            c.rect(x + 3, skin_top - 50, cw - 10, 16, fill=1, stroke=0)
            c.setFillColor(colors.HexColor('#D5D8DC'))  # bone/muscle
            c.rect(x + 3, skin_top - 62, cw - 10, 12, fill=1, stroke=0)

            # Damage
            dc = C_RED
            scx = x + (cw - 10) / 2 + 3
            if i == 0:
                c.setFillColor(dc)
                c.rect(scx - 8, skin_top - 4, 16, 4, fill=1, stroke=0)
            elif i == 1:
                c.setFillColor(dc)
                c.ellipse(scx - 10, skin_top - 22, scx + 10, skin_top - 4, fill=1, stroke=0)
            elif i == 2:
                c.setFillColor(dc)
                c.ellipse(scx - 10, skin_top - 38, scx + 10, skin_top - 4, fill=1, stroke=0)
            elif i >= 3:
                c.setFillColor(dc)
                c.ellipse(scx - 12, skin_top - 56, scx + 12, skin_top - 4, fill=1, stroke=0)

            # Header
            c.setFillColor(col)
            c.roundRect(x + 3, skin_top - 10, cw - 10, 12, 3, fill=1, stroke=0)
            c.setFillColor(fg); c.setFont('Helvetica-Bold', 7)
            c.drawCentredString(scx, skin_top - 4, stage)

            # Description
            c.setFillColor(C_LGRAY)
            c.roundRect(x + 3, skin_top - 62 - 70, cw - 10, 68, 4, fill=1, stroke=0)
            c.setFillColor(C_DARK); c.setFont('Helvetica', 7)
            for j, ln in enumerate(desc.split('\n')):
                c.drawCentredString(scx, skin_top - 76 - j * 11, ln)


# ─────────────────────────────────────────────────────────────────────────────
class BoneHealingDiagram(Flowable):
    """Bone healing phases diagram."""
    HEIGHT = 120

    def wrap(self, avW, avH):
        self._width = avW
        return avW, self.HEIGHT

    def draw(self):
        c = self.canv
        w = self._width
        phases = [
            ('HAEMATOMA', 'Hours-Days', C_RED, ['Blood clot fills', 'fracture site', 'Stems cells arrive']),
            ('SOFT CALLUS', 'Days-3wks', C_AMBER, ['Fibrocartilage', 'forms soft bridge', 'Flexible']),
            ('HARD CALLUS', '3-12wks', C_BLUE, ['Osteoblasts form', 'woven bone', 'More stable']),
            ('REMODELLING', 'Months-Yrs', C_GREEN, ['Woven → lamellar', 'Normal anatomy', 'restored']),
        ]
        bw = (w - 20) / 4 - 6
        for i, (name, timing, col, details) in enumerate(phases):
            x = 10 + i * (bw + 6)
            c.setFillColor(colors.HexColor('#CCCCCC'))
            c.roundRect(x + 2, 12, bw, 100, 6, fill=1, stroke=0)
            c.setFillColor(col)
            c.roundRect(x, 14, bw, 100, 6, fill=1, stroke=0)
            c.setFillColor(C_WHITE); c.setFont('Helvetica-Bold', 8)
            c.drawCentredString(x + bw/2, 97, name)
            c.setFont('Helvetica-Oblique', 7); c.setFillColor(colors.HexColor('#FDFEFE'))
            c.drawCentredString(x + bw/2, 84, timing)
            c.setFont('Helvetica', 7.5); c.setFillColor(C_WHITE)
            for j, d in enumerate(details):
                c.drawCentredString(x + bw/2, 66 - j * 12, d)
            if i < 3:
                ax = x + bw + 2
                draw_arrow(c, ax, 64, ax + 4, 64, C_GRAY, lw=2)


# ══════════════════════════════════════════════════════════════════════════════
#  TABLE HELPER
# ══════════════════════════════════════════════════════════════════════════════
def make_table(data, col_widths, header_bg=None, row_bgs=None, font_size=8.5):
    header_bg = header_bg or C_DARK
    row_bgs = row_bgs or [C_LGRAY, C_WHITE]
    t = Table(data, colWidths=col_widths)
    n_rows = len(data)
    n_cols = len(data[0])
    style = [
        ('BACKGROUND', (0, 0), (-1, 0), header_bg),
        ('TEXTCOLOR', (0, 0), (-1, 0), C_WHITE),
        ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
        ('FONTSIZE', (0, 0), (-1, -1), font_size),
        ('GRID', (0, 0), (-1, -1), 0.4, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ('TOPPADDING', (0, 0), (-1, -1), 5),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 5),
    ]
    for r in range(1, n_rows):
        bg = row_bgs[(r - 1) % len(row_bgs)]
        style.append(('BACKGROUND', (0, r), (-1, r), bg))
    t.setStyle(TableStyle(style))
    return t


# ══════════════════════════════════════════════════════════════════════════════
#  BUILD PDF
# ══════════════════════════════════════════════════════════════════════════════
def build_pdf():
    out = '/home/daytona/workspace/wound-healing/Wound_Healing_Study_Guide.pdf'

    # --- Draw cover on page 1 using low-level canvas, then build rest --------
    from reportlab.pdfgen import canvas as Canvas
    cv = Canvas.Canvas(out, pagesize=A4)
    pw, ph = A4

    # Background
    cv.setFillColor(C_DARK)
    cv.rect(0, 0, pw, ph, fill=1, stroke=0)

    # Decorative circles
    cv.setFillColor(colors.HexColor('#2C3E50'))
    cv.circle(pw * 0.88, ph * 0.88, 90, fill=1, stroke=0)
    cv.circle(pw * 0.1, ph * 0.12, 70, fill=1, stroke=0)
    cv.setFillColor(colors.HexColor('#34495E'))
    cv.circle(pw * 0.92, ph * 0.18, 50, fill=1, stroke=0)

    # Red accent stripe
    cv.setFillColor(C_RED)
    cv.rect(0, ph * 0.44, pw, 6, fill=1, stroke=0)

    # Chapter label
    cv.setFillColor(C_AMBER)
    cv.setFont('Helvetica-Bold', 14)
    cv.drawCentredString(pw / 2, ph * 0.84, 'CHAPTER 3 — SURGERY SERIES')

    # Main title
    cv.setFillColor(C_WHITE)
    cv.setFont('Helvetica-Bold', 36)
    cv.drawCentredString(pw / 2, ph * 0.73, 'WOUND HEALING')
    cv.setFont('Helvetica-Bold', 24)
    cv.drawCentredString(pw / 2, ph * 0.65, '& TISSUE REPAIR')

    # Subtitle
    cv.setFillColor(colors.HexColor('#BDC3C7'))
    cv.setFont('Helvetica', 12)
    cv.drawCentredString(pw / 2, ph * 0.55, 'Easy-to-Understand Study Guide')
    cv.drawCentredString(pw / 2, ph * 0.51, 'with Diagrams, Flowcharts & Key Tables')

    # Feature tags
    tags = ['Phases of Healing', 'Coagulation Cascade', 'Wound Classification',
            'Scar Management', 'Chronic Wounds', 'Wound Management']
    tag_w = (pw - 80) / 3
    for i, tag in enumerate(tags):
        col_i = i % 3; row_i = i // 3
        tx = 40 + col_i * (tag_w + 10)
        ty = ph * 0.38 - row_i * 36
        cv.setFillColor(C_BLUE)
        cv.roundRect(tx, ty, tag_w, 28, 5, fill=1, stroke=0)
        cv.setFillColor(C_WHITE)
        cv.setFont('Helvetica-Bold', 9)
        cv.drawCentredString(tx + tag_w / 2, ty + 10, tag)

    # Bottom bar
    cv.setFillColor(C_RED)
    cv.rect(0, 0, pw, 40, fill=1, stroke=0)
    cv.setFillColor(C_WHITE); cv.setFont('Helvetica', 10)
    cv.drawCentredString(pw / 2, 15, 'Comprehensive Medical Study Resource  |  Surgery / Wound Care / Plastic Surgery')

    cv.showPage()
    cv.save()

    # --- Now build the rest of the pages using platypus ----------------------
    from pypdf import PdfWriter, PdfReader

    # Build content pages to a temp file
    tmp = '/home/daytona/workspace/wound-healing/_tmp_content.pdf'
    doc = SimpleDocTemplate(
        tmp, pagesize=A4,
        leftMargin=MARGIN, rightMargin=MARGIN,
        topMargin=MARGIN, bottomMargin=MARGIN,
    )

    story = []
    sp = lambda n=6: Spacer(1, n)

    # ── SECTION 1: INTRO & PHASES ────────────────────────────────────────────
    story.append(Banner('1.  WHAT IS WOUND HEALING?', C_DARK))
    story.append(sp(8))
    story.append(Paragraph(
        'Wound healing is the body\'s natural process of repairing damaged tissue after injury. '
        'It is a complex, dynamic biological process. In adults, healing typically results in '
        '<b>fibrosis and scar formation</b>. Fascinatingly, fetal tissue can heal <b>without scarring</b> — '
        'this is a major focus of regenerative medicine research.',
        BODY))
    story.append(sp())
    story.append(InfoBox(
        'KEY CONCEPT: 4 Overlapping Phases of Normal Wound Healing',
        [
            'Phase 1 — HAEMOSTASIS (0-30 min):  Stop the bleeding',
            'Phase 2 — INFLAMMATION (Day 1-5):  Clean the wound',
            'Phase 3 — PROLIFERATION (Day 3 – 3 weeks):  Rebuild the tissue',
            'Phase 4 — REMODELLING (3 weeks – 2 years):  Strengthen the scar',
            '',
            'IMPORTANT: Phases OVERLAP — they are not sequential on/off switches!',
        ],
        bg=C_LBLUE, title_col=C_BLUE
    ))
    story.append(sp(10))

    story.append(Paragraph('DIAGRAM 1: The 4 Phases of Wound Healing', H2))
    story.append(PhaseDiagram())
    story.append(sp(10))

    story.append(Paragraph('DETAILED PHASE BREAKDOWN', H2))
    phase_data = [
        ['PHASE', 'TIMING', 'KEY CELLS', 'WHAT HAPPENS', 'SIGNS'],
        ['1. HAEMOSTASIS', '0–30 min', 'Platelets', 'Vasoconstriction\nPlatelet plug\nBlood clot forms', 'Bleeding stops'],
        ['2. INFLAMMATION', 'Day 1–5', 'Neutrophils (d1-2)\nMacrophages (d2-3)', 'Kill bacteria\nRemove debris\nRelease growth factors', 'Rubor, Tumor\nCalor, Dolor\n(Red, Swollen\nHot, Painful)'],
        ['3. PROLIFERATION', 'Day 3–3wks', 'Fibroblasts', 'New collagen\nAngiogenesis\nRe-epithelialisation', 'Pink granulation\ntissue forms'],
        ['4. REMODELLING', '3wks–2yrs', 'Fibroblasts\nCollagen', 'Type III → Type I\nCollagen cross-links\nWound contracts', 'Scar flattens\nFades, hardens\n80% strength'],
    ]
    pt = make_table(phase_data,
                    col_widths=[3*cm, 2*cm, 3.5*cm, 4.5*cm, 3*cm],
                    header_bg=C_DARK,
                    row_bgs=[C_LRED, colors.HexColor('#FEF5E7'), C_LBLUE, C_LGREEN])
    story.append(pt)
    story.append(PageBreak())

    # ── SECTION 2: HAEMOSTASIS & COAGULATION ─────────────────────────────────
    story.append(Banner('2.  HAEMOSTASIS — STOPPING THE BLEED', C_RED))
    story.append(sp(8))
    story.append(Paragraph(
        'When a blood vessel is injured, the body immediately triggers a multi-step response '
        'to stop blood loss. There are <b>two pathways</b> (intrinsic and extrinsic) that both '
        'converge on a <b>common pathway</b> to form a stable blood clot.',
        BODY))
    story.append(sp(6))
    story.append(Paragraph('FLOWCHART 2: The Coagulation Cascade', H2))
    story.append(CoagDiagram())
    story.append(sp(8))

    story.append(Paragraph('PLATELET ACTIVATION STEPS', H2))
    plat_data = [
        ['STEP', 'WHAT HAPPENS', 'WHY IT MATTERS'],
        ['1. Adhesion', 'Platelets stick to exposed subendothelial collagen\nafter vessel wall damaged', 'First responders to injury site'],
        ['2. Activation', 'Alpha granules release TGF-β, PDGF, FGF, VEGF\n(growth factors)', 'Signals start of healing cascade'],
        ['3. Aggregation', 'Platelets clump together\nForms mechanical "platelet plug"', 'Physical barrier to blood loss'],
        ['4. Coagulation', 'Coagulation cascade triggered\nFibrin clot forms around plug', 'Creates stable permanent clot'],
    ]
    story.append(make_table(plat_data, [3*cm, 7*cm, 6*cm], header_bg=C_RED,
                            row_bgs=[C_LRED, C_WHITE]))
    story.append(sp(8))

    story.append(InfoBox('EASY MEMORY: Coagulation Cascade', [
        'INTRINSIC:  Hageman (XII) → XI → IX → VIII → activates Factor X',
        'EXTRINSIC:  Tissue injury → Tissue Factor + VII → activates Factor X',
        'COMMON:     X → Prothrombin → Thrombin → Fibrinogen → FIBRIN CLOT',
        'Factor XIII cross-links fibrin to make the clot stable',
        'FIBRINOLYSIS: Plasminogen → Plasmin (via tPA/uPA) breaks down the clot',
    ], bg=C_LRED, title_col=C_RED))
    story.append(PageBreak())

    # ── SECTION 3: TYPES OF HEALING ──────────────────────────────────────────
    story.append(Banner('3.  TYPES OF WOUND HEALING', C_GREEN))
    story.append(sp(8))
    story.append(Paragraph(
        'There are three types of wound healing, depending on how the wound is treated '
        'and whether the edges are brought together.',
        BODY))
    story.append(sp(6))
    story.append(Paragraph('FLOWCHART 3: Types of Wound Healing', H2))
    story.append(HealingTypesDiagram())
    story.append(sp(8))

    story.append(Paragraph('COMPARISON TABLE', H2))
    ht_data = [
        ['TYPE', 'ALSO KNOWN AS', 'METHOD', 'EXAMPLES', 'RESULT'],
        ['PRIMARY', '1st Intention', 'Edges sutured\nor stapled\ntogether', 'Surgical cut\nClean laceration', 'Least scar\nFastest\nBest cosmesis'],
        ['SECONDARY', '2nd Intention', 'Left open\nHeals by\ngranulation', 'Infected wound\nPressure ulcer\nAbscess', 'More scarring\nSlower\nMore contraction'],
        ['TERTIARY', 'Delayed Primary\n3rd Intention', 'Open first\nThen closed\nlater', 'Contaminated wounds\nBite wounds\nGunshot wounds', 'Good result\nControlled infection\nIntermediate'],
    ]
    story.append(make_table(ht_data, [2.5*cm, 3*cm, 3.5*cm, 4*cm, 3*cm],
                            header_bg=C_GREEN,
                            row_bgs=[C_LGREEN, colors.HexColor('#D5F5E3')]))
    story.append(PageBreak())

    # ── SECTION 4: WOUND CLASSIFICATION ──────────────────────────────────────
    story.append(Banner('4.  CLASSIFICATION OF WOUNDS', C_PURPLE))
    story.append(sp(8))
    story.append(Paragraph(
        'Wounds are classified in multiple ways. The most important system is the '
        '<b>CDC surgical wound classification</b> which stratifies the risk of surgical site '
        'infection (SSI).',
        BODY))
    story.append(sp(6))
    story.append(Paragraph('DIAGRAM 4: CDC Wound Classification by SSI Risk', H2))
    story.append(WoundClassDiagram())
    story.append(sp(10))

    story.append(Paragraph('OTHER CLASSIFICATION SYSTEMS', H2))
    class_data = [
        ['CLASSIFY BY', 'CATEGORIES', 'EXAMPLES'],
        ['AETIOLOGY\n(Cause)', 'Clean, Surgical, Shearing,\nDegloving, Crush, Blast,\nBurn, Bite', 'Knife = clean surgical\nCar crash = crush\nExplosion = blast'],
        ['DEPTH', 'Epidermal (surface only)\nDermal (into skin layers)\nFull thickness (all layers)', 'Graze = epidermal\nDeep cut = dermal\nPressure ulcer = full'],
        ['CONTAMINATION', 'Clean → Clean-contaminated\n→ Contaminated → Dirty', 'Increases infection risk\nand SSI rate'],
        ['COMPLEXITY', 'Simple vs Complex\n(with infection, necrosis,\ngas gangrene, compartment\nsyndrome)', 'Paper cut = simple\nGunshot = complex'],
    ]
    story.append(make_table(class_data, [3.5*cm, 6*cm, 6.5*cm], header_bg=C_PURPLE,
                            row_bgs=[C_LPUR, C_WHITE]))
    story.append(PageBreak())

    # ── SECTION 5: ABNORMAL HEALING ──────────────────────────────────────────
    story.append(Banner('5.  WHEN HEALING GOES WRONG (Abnormal Wound Healing)', C_RED))
    story.append(sp(8))
    story.append(Paragraph(
        'Some wounds fail to heal in a timely and orderly manner, leading to chronic wounds, '
        'significant morbidity, and poor cosmetic outcomes. Factors can be local (at the wound) '
        'or systemic (throughout the body).',
        BODY))
    story.append(sp(6))
    story.append(Paragraph('FLOWCHART 5: Factors That Impair Wound Healing', H2))
    story.append(AbnormalFlowchart())
    story.append(sp(8))

    story.append(Paragraph('QUICK-REFERENCE FACTOR TABLE', H2))
    fact_data = [
        ['LOCAL FACTORS', 'WHY HARMFUL', 'SYSTEMIC FACTORS', 'WHY HARMFUL'],
        ['Skin tension', 'Pulls wound edges apart', 'Old age', 'Slower cellular repair'],
        ['Hypoxia/Ischaemia', 'Cells need O2 to heal', 'Obesity', 'Poor tissue perfusion'],
        ['Vascular disease', 'Less blood = less nutrients', 'Malnutrition', 'No protein for new tissue'],
        ['Infection', 'Bacteria destroy tissue', 'Smoking', 'Reduces blood O2 levels'],
        ['Foreign bodies', 'Continuous inflammation', 'Diabetes mellitus', 'Neuropathy + poor vessels'],
        ['Radiotherapy', 'Damages microvessels', 'Steroids/NSAIDs', 'Suppress healing inflammation'],
        ['Haematoma', 'Breeding ground for infection', 'Chemotherapy', 'Kills fast-dividing repair cells'],
    ]
    ft = Table(fact_data, colWidths=[4*cm, 4.5*cm, 4*cm, 4.5*cm])
    ft.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (1, 0), C_RED),
        ('BACKGROUND', (2, 0), (3, 0), C_BLUE),
        ('TEXTCOLOR', (0, 0), (-1, 0), C_WHITE),
        ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
        ('FONTSIZE', (0, 0), (-1, -1), 8.5),
        ('ROWBACKGROUNDS', (0, 1), (-1, -1), [C_LRED, C_WHITE]),
        ('GRID', (0, 0), (-1, -1), 0.4, colors.HexColor('#CCCCCC')),
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ('TOPPADDING', (0, 0), (-1, -1), 5),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 5),
    ]))
    story.append(ft)
    story.append(PageBreak())

    # ── SECTION 6: SCAR TYPES ────────────────────────────────────────────────
    story.append(Banner('6.  TYPES OF ABNORMAL SCARS', C_AMBER))
    story.append(sp(8))
    story.append(Paragraph(
        'Excessive or abnormal wound healing can result in two main types of problem scars: '
        '<b>hypertrophic scars</b> (raised but within wound boundary) and '
        '<b>keloid scars</b> (extend beyond wound boundary and do not regress).',
        BODY))
    story.append(sp(6))
    story.append(Paragraph('DIAGRAM 6: Normal vs Hypertrophic vs Keloid Scar', H2))
    story.append(ScarDiagram())
    story.append(sp(10))

    scar_cmp = [
        ['FEATURE', 'NORMAL SCAR', 'HYPERTROPHIC', 'KELOID'],
        ['Boundary', 'Within wound', 'Within wound', 'BEYOND wound'],
        ['Regression', 'Yes — fades', 'Yes — regresses', 'NO — never regresses'],
        ['Collagen', 'Organised/parallel', 'Nodular/disorganised', 'Very disorganised'],
        ['Common in', 'Any wound', 'High tension areas\nDeep burns', 'Chest, earlobes, jaw\nDarker skin tone'],
        ['Treatment', 'Not needed', 'Silicone + steroids\nLaser if needed', 'Steroids + 5-FU\n+ Laser + Surgery'],
    ]
    story.append(make_table(scar_cmp, [3.5*cm, 3.5*cm, 4*cm, 5*cm], header_bg=C_DARK,
                            row_bgs=[C_LYELL, C_WHITE]))
    story.append(PageBreak())

    # ── SECTION 7: SCAR MANAGEMENT ───────────────────────────────────────────
    story.append(Banner('7.  SCAR MANAGEMENT ALGORITHM', C_PURPLE))
    story.append(sp(8))
    story.append(Paragraph(
        'Scar management follows a <b>step-up approach</b>: start with the simplest treatment '
        'and escalate if the scar persists. Prevention always beats treatment.',
        BODY))
    story.append(sp(6))
    story.append(Paragraph('FLOWCHART 7: Scar Management (Hypertrophic vs Keloid)', H2))
    story.append(ScarMgmtFlowchart())
    story.append(sp(8))

    story.append(InfoBox('PREVENTION IS BETTER THAN TREATMENT', [
        '1. Plan incisions along Langer lines (natural skin tension lines)',
        '2. Handle tissue gently — meticulous surgical technique',
        '3. Close without tension — correct layer-by-layer suturing',
        '4. Start silicone gel/sheeting early (as soon as wound is epithelialised)',
        '5. Protect scar from sun exposure (UV worsens pigmentation)',
        '6. Regular scar massage after 6 weeks',
    ], bg=C_LPUR, title_col=C_PURPLE))
    story.append(PageBreak())

    # ── SECTION 8: WOUND MANAGEMENT ──────────────────────────────────────────
    story.append(Banner('8.  WOUND MANAGEMENT — How to Treat a Wound', C_BLUE))
    story.append(sp(8))
    story.append(Paragraph(
        'Wound management follows four systematic steps: '
        '<b>Prepare → Wound → Closure → Follow-up</b>. '
        'Clinical judgement is key at each stage.',
        BODY))
    story.append(sp(6))

    mgmt = [
        ['STEP', 'ACTIONS', 'KEY NOTES'],
        ['PREPARATION', '• Antibiotic prophylaxis\n• Tetanus prophylaxis\n• Adequate anaesthesia\n• Wound irrigation (warm saline)',
         'Give tetanus if:\n- Not vaccinated\n- High-risk wound\n- Booster >10yrs ago'],
        ['WOUND CARE', '• Early debridement\n• Exploration of wound\n• Repair structures\n  (tendons, nerves, vessels)\n• Achieve haemostasis',
         'Debridement types:\n- Surgical (fastest)\n- Mechanical (irrigation)\n- Autolytic (dressings)\n- Enzymatic\n- Biological (maggots)'],
        ['CLOSURE', '• Skin closure WITHOUT tension\n• Consider reconstruction ladder\n• Appropriate suture choice\n• Consider drains\n• Optimal dressings',
         'Reconstruction ladder:\n1. Direct closure\n2. Skin graft\n3. Local flap\n4. Free flap'],
        ['FOLLOW-UP', '• Remove sutures at correct time\n• Physiotherapy if needed\n• Monitor for complications\n• Start scar management',
         'Suture timing:\nFace: 5 days\nAbdomen: 10 days\nLimbs: 10-14 days'],
    ]
    story.append(make_table(mgmt, [3*cm, 7.5*cm, 5.5*cm], header_bg=C_BLUE,
                            row_bgs=[C_LBLUE, C_WHITE]))
    story.append(sp(10))

    story.append(Paragraph('TYPES OF DEBRIDEMENT', H2))
    deb = [
        ['TYPE', 'HOW IT WORKS', 'BEST FOR'],
        ['SURGICAL', 'Scalpel/scissors removes dead tissue\nuntil healthy bleeding seen', 'Any devitalised wound\nFastest method'],
        ['MECHANICAL', 'High-pressure irrigation\nWet-to-dry dressings', 'Non-selective (removes\nsome healthy tissue too)'],
        ['AUTOLYTIC', 'Hydrocolloid/transparent dressings\nKeep moist; own enzymes digest slough', 'Clean wounds\nSlow but gentle'],
        ['ENZYMATIC', 'Collagenase or papain-urea\napplied topically', 'When surgery not possible'],
        ['BIOLOGICAL', 'Medical maggots (Lucilla sericata)\nEat dead tissue; antimicrobial secretions', 'Chronic wounds\nWhen others fail'],
    ]
    story.append(make_table(deb, [2.8*cm, 7*cm, 6.2*cm], header_bg=C_NAVY,
                            row_bgs=[C_LBLUE, C_WHITE]))
    story.append(PageBreak())

    # ── SECTION 9: CHRONIC WOUNDS ────────────────────────────────────────────
    story.append(Banner('9.  CHRONIC WOUNDS', colors.HexColor('#7B241C')))
    story.append(sp(8))
    story.append(Paragraph(
        'Chronic wounds fail to progress through normal healing stages. They are stuck in '
        'the inflammatory phase, with persistent infection and prolonged inflammation. '
        'The most common comorbidity is <b>diabetes mellitus</b>.',
        BODY))
    story.append(sp(6))

    cw_data = [
        ['TYPE', 'CAUSE', 'LOCATION', 'KEY SIGN', 'TREATMENT'],
        ['PRESSURE ULCER', 'Sustained pressure\nover bone compresses\nblood supply', 'Sacrum, heel,\nischium,\nmalleolus', 'Stage 1-4\nPREVENTABLE', 'Reposition\nDebride\nDressings'],
        ['VENOUS ULCER', 'Venous hypertension\nBlood pools in leg\nSkin breaks down', 'Above medial\nmalleolus', 'Sloughy base\nOedema\nIrregular edge', 'Compression\nbandaging\nElevation'],
        ['ARTERIAL ULCER', 'Ischaemia from\npoor arterial\nblood supply', 'Toes, lateral\nankle', 'Punched-out\nPainful\nCold pale limb', 'Revascularisation\nSurgery'],
        ['DIABETIC ULCER', 'Neuropathy (no pain)\n+ poor circulation', 'Foot pressure\npoints', 'PAINLESS!\nDeep, slow\nhealing', 'Offloading\nAntibiotics\nDebride'],
        ['NECROTISING\nFASCIITIS', 'Severe bacterial\ninfection (Strep A)\nDestroys fascia', 'Any area\n(limbs\ncommon)', 'EMERGENCY!\nDishwasher pus\nRapid spread', 'IV antibiotics\nSurgical\ndebridement'],
    ]
    story.append(make_table(cw_data, [3*cm, 3.5*cm, 2.8*cm, 3*cm, 3.7*cm],
                            header_bg=colors.HexColor('#7B241C'),
                            row_bgs=[C_LRED, C_WHITE]))
    story.append(sp(10))

    story.append(Paragraph('DIAGRAM 9: Pressure Ulcer Staging', H2))
    story.append(PressureUlcerDiagram())
    story.append(sp(6))

    stage_d = [
        ['STAGE', 'DEPTH', 'APPEARANCE', 'MANAGEMENT'],
        ['Stage 1', 'Intact skin', 'Non-blanchable erythema\nNo skin break', 'Reposition q2h\nProtective dressing'],
        ['Stage 2', 'Partial thickness\nEpidermis/dermis', 'Shallow open ulcer\nor intact/ruptured blister', 'Moist dressings\nRelieve pressure'],
        ['Stage 3', 'Full thickness\nSubcutaneous visible', 'Deep crater\nFat may be visible', 'Debridement\nAdvanced dressings'],
        ['Stage 4', 'Full thickness\nBone/tendon exposed', 'Exposed bone/muscle\nOften infected', 'Surgery often needed\nReconstruction flap'],
        ['Unstageable', 'Unknown depth\n(covered by slough)', 'Cannot see\nwound base', 'Debride first\nthen re-stage'],
    ]
    story.append(make_table(stage_d, [2.5*cm, 3.5*cm, 4.5*cm, 5.5*cm],
                            header_bg=colors.HexColor('#7B241C'),
                            row_bgs=[C_LRED, C_WHITE]))
    story.append(PageBreak())

    # ── SECTION 10: BONE HEALING ─────────────────────────────────────────────
    story.append(Banner('10.  HEALING IN OTHER TISSUES', C_NAVY))
    story.append(sp(8))
    story.append(Paragraph('<b>A.  BONE HEALING</b>', H2))
    story.append(Paragraph(
        'Bone heals through <b>callus formation</b> (indirect/secondary healing). '
        'Think of callus as temporary scaffolding that gets progressively replaced by proper bone. '
        'Primary bone healing (no callus) only occurs when fracture ends are rigidly fixed.',
        BODY))
    story.append(sp(6))
    story.append(Paragraph('DIAGRAM 10A: Stages of Bone Healing', H2))
    story.append(BoneHealingDiagram())
    story.append(sp(6))

    bone_d = [
        ['STAGE', 'TIMING', 'WHAT FORMS', 'KEY CELLS'],
        ['Haematoma', 'Hours–Days', 'Blood clot fills fracture\nBrings MSCs and growth factors', 'Platelets, Macrophages'],
        ['Soft Callus', 'Days–3wks', 'Fibrocartilage bridging callus\nFlexible, not rigid', 'Chondrocytes, Fibroblasts'],
        ['Hard Callus', '3–12 wks', 'Woven bone formed by osteoblasts\nFracture becomes stable', 'Osteoblasts'],
        ['Remodelling', 'Months–Years', 'Woven → Lamellar bone\nNormal anatomy restored', 'Osteoblasts + Osteoclasts'],
    ]
    story.append(make_table(bone_d, [3*cm, 3*cm, 6*cm, 4*cm], header_bg=C_NAVY,
                            row_bgs=[C_LBLUE, C_WHITE]))
    story.append(sp(10))

    story.append(Paragraph('<b>B.  NERVE HEALING (Peripheral Nerve)</b>', H2))
    story.append(Paragraph(
        'Peripheral nerves regenerate slowly via <b>Wallerian degeneration</b> followed by guided '
        'axon regrowth. Rate of regrowth: <b>~1 mm per day</b>.',
        BODY))

    nerve_d = [
        ['STAGE', 'WHAT HAPPENS', 'KEY POINT'],
        ['Injury', 'Axon cut or compressed\nDistal segment degenerates (Wallerian)', 'Immediate; irreversible distally'],
        ['Degeneration', 'Macrophages clear myelin debris\nSchwann cells proliferate, form bands\nof Bungner to guide axon', 'Days–Weeks'],
        ['Regeneration', 'Axon sprouts from proximal stump\nGuided by Schwann cell tubes\nNeurotrophism drives direction', 'Weeks–Months'],
        ['Recovery', 'Axon reaches target organ\nRemyelination by Schwann cells\nPartial function restored', 'Months–Years'],
    ]
    story.append(make_table(nerve_d, [2.5*cm, 8.5*cm, 5*cm], header_bg=C_NAVY,
                            row_bgs=[C_LBLUE, C_WHITE]))
    story.append(sp(8))

    story.append(Paragraph('<b>C.  TENDON HEALING</b>', H2))
    story.append(Paragraph(
        'Tendons have two mechanisms of nutrient delivery: '
        '<b>intrinsic</b> (via blood from vincula) and <b>extrinsic</b> (synovial diffusion from tendon sheath). '
        'Early mobilisation after tendon repair promotes intrinsic healing and prevents adhesions. '
        'Tendons must be splinted to avoid rupture during healing.',
        BODY))
    story.append(PageBreak())

    # ── SECTION 11: ACUTE WOUNDS ─────────────────────────────────────────────
    story.append(Banner('11.  SPECIFIC ACUTE WOUNDS', C_TEAL))
    story.append(sp(8))

    story.append(Paragraph('A.  BITES', H2))
    bite_d = [
        ['BITE TYPE', 'RISK ORGANISMS', 'MANAGEMENT'],
        ['Human bite\n(esp. fist-to-tooth)', 'Streptococcus, Staphylococcus\nEikenella corrodens\n(HIGH RISK!)', 'Treat as contaminated\nExplore joint if involved\nIV antibiotics; do NOT close primarily'],
        ['Dog / Animal', 'Pasteurella multocida\nCapnocytophaga\nRabies (endemic areas)', 'Thorough washing\nConsider rabies prophylaxis\nAntibiotics + tetanus'],
    ]
    story.append(make_table(bite_d, [3*cm, 5*cm, 8*cm], header_bg=C_TEAL,
                            row_bgs=[C_LGREEN, C_WHITE]))
    story.append(sp(8))

    story.append(Paragraph('B.  ACUTE COMPARTMENT SYNDROME', H2))
    story.append(InfoBox('ACUTE COMPARTMENT SYNDROME — SURGICAL EMERGENCY!', [
        'WHAT: Pressure rises in a closed fascial compartment → blood cannot enter → ischaemia',
        'CAUSES: Fractures (most common), crush injuries, burns, tight casts',
        '5 Ps (Signs):',
        '   1. Pain (out of proportion — hallmark!) 2. Pressure (tight compartment)',
        '   3. Paraesthesia (tingling/numbness)     4. Paresis (weakness)',
        '   5. Pallor (late sign — poor prognosis)',
        'DIAGNOSIS: Compartment pressure ≥30 mmHg (or within 30 mmHg of diastolic BP)',
        'TREATMENT: EMERGENCY FASCIOTOMY — incise all compartments',
        'DELAY = irreversible ischaemia, Volkmanns contracture, rhabdomyolysis, death',
    ], bg=C_LRED, title_col=C_RED))
    story.append(sp(8))

    story.append(Paragraph('C.  NECROTISING FASCIITIS', H2))
    story.append(InfoBox('NECROTISING FASCIITIS — Life-threatening Emergency', [
        'Severe rapidly progressing infection of soft tissue and fascia',
        'Most common: Streptococcus pyogenes (Group A) or polymicrobial',
        'LOCAL SIGNS: Unusual pain, erythema, oedema, crepitus, blisters,',
        '             grey "dishwasher pus", fixed staining, necrosis, gangrene',
        'SYSTEMIC: Fever, tachycardia, shock, coagulopathy, multiorgan failure',
        'TREATMENT: Urgent IV antibiotics + RADICAL surgical debridement',
        'Mortality: 26-40% even with treatment (Danish cohort >1500 patients)',
    ], bg=C_LRED, title_col=colors.HexColor('#7B241C')))
    story.append(PageBreak())

    # ── SECTION 12: MASTER SUMMARY ───────────────────────────────────────────
    story.append(Banner('12.  MASTER QUICK-REFERENCE SUMMARY', C_DARK))
    story.append(sp(8))

    summary = [
        ['TOPIC', 'KEY POINTS'],
        ['4 Phases', 'Haemostasis (0-30min) → Inflammation (d1-5) → Proliferation (d3-3wks) → Remodelling (3wks-2yrs)'],
        ['Haemostasis', 'Vasoconstriction → Platelet adhesion → Activation → Aggregation → Coagulation → Stable clot'],
        ['Coagulation', 'Intrinsic + Extrinsic → Common: X→Thrombin→Fibrin→Stable clot (XIII cross-links)'],
        ['Inflammation signs', 'Rubor (red) + Tumor (swollen) + Calor (hot) + Dolor (pain) = RTCD'],
        ['Healing types', 'Primary = closed; Secondary = open (granulation); Tertiary = delayed closure'],
        ['Wound classes', 'I (Clean) → II (Clean-contaminated) → III (Contaminated) → IV (Dirty)'],
        ['Abnormal healing', 'Local: infection, tension, ischaemia | Systemic: DM, obesity, steroids, smoking, age'],
        ['Hypertrophic vs Keloid', 'Hypertrophic = stays in wound, regresses | Keloid = grows BEYOND wound, never regresses'],
        ['Scar treatment', 'Step 1: Silicone gel | Step 2: Steroids | Step 3: Laser | Step 4: Surgery'],
        ['Pressure ulcers', 'Stage 1: redness | Stage 2: blister | Stage 3: deep crater | Stage 4: bone exposed'],
        ['Debridement', 'Surgical > Mechanical > Autolytic > Enzymatic > Biological (maggots)'],
        ['Compartment syndrome', '5 Ps: Pain, Pressure, Paraesthesia, Paresis, Pallor → FASCIOTOMY'],
        ['Bone healing', 'Haematoma → Soft callus (fibrocartilage) → Hard callus (woven bone) → Remodelling'],
        ['Nerve regeneration', 'Wallerian degeneration → Schwann cell tubes → Axon regrows ~1 mm/day'],
        ['Tetanus-prone wounds', 'Puncture, bite, compound fracture, foreign body, >6hr old, devitalised tissue'],
    ]
    story.append(make_table(summary, [4.5*cm, 11.5*cm], header_bg=C_DARK,
                            row_bgs=[C_LBLUE, C_WHITE], font_size=8))
    story.append(sp(10))

    story.append(InfoBox('EXAM MNEMONICS', [
        'RTCD = Rubor, Tumor, Calor, Dolor (cardinal signs of inflammation)',
        '5 Ps of Compartment Syndrome = Pain, Pressure, Paraesthesia, Paresis, Pallor',
        'KELOID = K for "Kollagen beyond boundary" — grows OUTSIDE the wound edge',
        'Nerve growth = 1 mm/day = very slow (plan for months-years recovery)',
        'Wound classes I-IV: think "how dirty is it?" — more dirty = higher SSI risk',
        'Tetanus prone wounds: remember PACE = Puncture, Animal bite, Contaminated, Extensive tissue loss',
    ], bg=C_LYELL, title_col=colors.HexColor('#B7950B')))

    doc.build(story)

    # ── Merge cover + content ─────────────────────────────────────────────────
    writer = PdfWriter()
    for f in [out, tmp]:
        r = PdfReader(f)
        for pg in r.pages:
            writer.add_page(pg)

    import os
    os.rename(out, '/home/daytona/workspace/wound-healing/_cover.pdf')

    writer2 = PdfWriter()
    cover_r = PdfReader('/home/daytona/workspace/wound-healing/_cover.pdf')
    content_r = PdfReader(tmp)
    for pg in cover_r.pages:
        writer2.add_page(pg)
    for pg in content_r.pages:
        writer2.add_page(pg)

    with open(out, 'wb') as f_out:
        writer2.write(f_out)

    os.remove('/home/daytona/workspace/wound-healing/_cover.pdf')
    os.remove(tmp)

    print(f'PDF built: {out}')
    return out


if __name__ == '__main__':
    build_pdf()
This is a shared conversation. Sign in to Orris to start your own chat.