Posterior approach to elbow in orthopaedics 10 marks pg answer with flow chart and images

Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Loading Image
Loading Image
Loading Image
Loading Image
Loading Image
Loading Image
I now have comprehensive textbook content and all key images. Let me compile the complete 10-mark answer.

Posterior Approach to the Elbow

Sources: Campbell's Operative Orthopaedics 15th Ed 2026; Miller's Review of Orthopaedics 9th Ed

Overview

The posterior approach is the workhorse approach to the elbow joint. It provides excellent exposure of the distal humerus, trochlea, capitellum, olecranon, and radial head. Unlike most surgical approaches, the posterior approach has no true internervous plane - access is gained by dealing with the triceps mechanism in one of several ways.

Surgical Anatomy

StructureRelevance
Triceps tendonMain obstacle; must be reflected, split, or detached to enter the joint
Ulnar nerveRuns in the cubital tunnel (medial epicondyle groove); at risk in ALL posterior approaches
OlecranonBlocks direct joint access; may be osteotomized for maximum exposure
AnconeusLateral landmark; reflects subperiosteally to expose radial head
Radial nerveLimits proximal extension along humerus

Flowchart: Choosing the Posterior Approach

POSTERIOR APPROACH TO ELBOW
           |
           ▼
   What is the surgical need?
           |
    ┌──────┴──────────────────────┐
    |                             |
Maximum articular        Triceps preservation
exposure needed          (elbow arthroplasty,
(intraarticular          elderly, soft tissue)
fractures, ORIF)
    |                             |
    ▼                             ▼
OLECRANON OSTEOTOMY        EXTENSILE (BRYAN-MORREY)
(MacAusland & Müller)       APPROACH
- Chevron osteotomy         - Triceps reflected as
  at bare zone                one unit medial→lateral
- Best articular access     - Ulnar nerve transposed
- Tension band/lag          - No olecranon division
  screw fixation                     |
                                      ▼
                             Also consider:
                         ┌───────────┴──────────┐
                    TRICEPS SPLITTING     PARATRICIPITAL
                    (midline split,       (Triceps SLIDE)
                    olecranon intact)     Elevate off
                                         intermuscular septa

Variants of Posterior Approach

1. Posterior Approach by Olecranon Osteotomy (MacAusland & Müller)

Indication: Best exposure of distal humeral articular surface (intraarticular fractures, distal humeral ORIF). Wilkinson and Stanley demonstrated this exposes significantly more articular surface than a triceps-reflecting approach.
Patient Position: Lateral decubitus or prone, arm supported with elbow flexed.
Incision: Straight posterior midline - begins 5 cm distal to the olecranon tip, extends proximally medial to the midline to 10-12 cm above the olecranon.
Steps:
  1. Reflect skin and subcutaneous tissue on both sides
  2. Isolate the ulnar nerve and retract gently (Penrose drain or moist tape)
  3. Pre-drill fixation hole before osteotomy (avoid losing track of reduction later)
  4. Identify the bare zone of the olecranon (the non-articular strip at ~2 cm from tip) - use fluoroscopy or direct visualization; place a K-wire at the apex
  5. Mark a 60-degree chevron osteotomy with apex at the bare zone
  6. Divide 3/4 of the depth with a thin oscillating saw
  7. Fracture the remaining 1/4 with an osteotome - this avoids saw kerf through articular cartilage
  8. Reflect the olecranon fragment + attached triceps proximally - full distal humerus exposure
  9. At closure: reduce fragment and fix with lag screw (6.5 mm) + tension band wire
Posterior approach to elbow: (A) Superficial exposure showing olecranon osteotomy and ulnar nerve. (B) Deep exposure revealing trochlea, periosteum, and olecranon
Fig. 2.34 - Posterior approach to the elbow. (A) Superficial exposure. (B) Deep exposure with olecranon osteotomy.

Olecranon osteotomy technique: (A) Pre-drilling for 6.5mm screw, (B) Incomplete chevron osteotomy, (C) Completed by fracture, (D) Lag screw and tension band wire fixation
Fig. 1.124 - Olecranon osteotomy. A: Pre-drilling. B: Incomplete chevron cut. C: Osteotomy completed by fracturing. D: 6.5 mm lag screw and tension band wire fixation.

2. Extensile Posterior Approach - Bryan and Morrey (Triceps-Sparing)

Indication: Total elbow arthroplasty, elderly patients, when triceps continuity is paramount.
Advantage: Preserves the triceps mechanism as a continuous unit, allowing easy repair and rapid rehabilitation.
Position: Lateral decubitus or 45-60° tilt with sandbags. Arm placed across the chest.
Incision: Straight posterior midline - 7 cm distal to olecranon tip to 9 cm proximal.
Steps:
  1. Find the ulnar nerve at the medial border of the medial head of triceps - dissect free to first motor branch
  2. In total elbow arthroplasty: transpose nerve anteriorly into subcutaneous tissue
  3. Elevate medial aspect of triceps from the humerus along the intermuscular septum to the posterior capsule
  4. Incise the superficial forearm fascia distally ~6 cm to the periosteum of the medial olecranon
  5. Reflect the periosteum + fascia as a single unit from medial to lateral (weakest point = medial junction of triceps insertion + superficial fascia + ulnar periosteum - take care here!)
  6. Extend elbow 20-30° during this step to relieve tension on the tissue
  7. Reflect anconeus subperiosteally from proximal ulna to expose the radial head
  8. The entire joint is now widely exposed; posterior capsule usually elevates with triceps mechanism
  9. Tip of olecranon may be resected to expose the trochlea clearly
Closure:
  • Repair MCL if released
  • Return triceps to anatomic position; suture through transosseous holes in proximal ulna
  • Suture periosteum to superficial forearm fascia as far as the FCU margin
  • Dress wound with elbow at 60° flexion (in TEA) to avoid pressure from olecranon tip

Bryan-Morrey extensile posterior approach (A): Skin incision - lateral view showing skin incision line, patient positioning prone with elbow flexed, and superficial layer showing ulnar nerve and triceps tendon with dashed line of incision. (C): Deep exposure with capitellum, radius, anconeus, and extensor carpi ulnaris visible
Fig. 1.123 - Wadsworth/Bryan-Morrey posterior approach. A: Skin incision (curved, paramedian). B: Triceps-ulnar periosteal reflection. C: Complete exposure with capitellum, radius, anconeus.

Bryan-Morrey approach: superficial layer showing olecranon, superficial forearm fascia, line of incision, medial epicondyle, ulnar nerve, and triceps muscle
Bryan-Morrey: Step A - Superficial exposure. The ulnar nerve is identified and the line of incision through the fascia-periosteum unit is marked (dashed green line).

Bryan-Morrey approach Step B: elevation of triceps and ulnar nerve identification at medial epicondyle
Bryan-Morrey: Step B - Ulnar nerve retracted, medial epicondyle visible, triceps being elevated from humerus.

Bryan-Morrey approach Step C: deep exposure with joint capsule, medial epicondyle, ulnar nerve, FCU, and ulnar periosteum reflected
Bryan-Morrey: Step C - Deep exposure. Forearm fascia + ulnar periosteum reflected. Joint capsule, medial epicondyle, and FCU visible.

3. Other Posterior Variants

VariantIntervalKey Feature
Triceps SplittingMidline split of tricepsOlecranon intact; limited exposure
Paratricipital (Triceps Slide)Triceps elevated off medial + lateral intermuscular septaTriceps insertion undisturbed; mobilized either direction

Structures at Risk

StructureMechanism of Injury
Ulnar nerveDirect injury during dissection; excessive retraction; most common complication
Radial nerveLimits proximal extension along the humerus
Triceps mechanismOver-tension during reflection (Bryan-Morrey) - extend elbow 20-30° to protect
Articular cartilageSaw kerf during osteotomy - always fracture final 1/4 with osteotome

Indications Summary

IndicationPreferred Variant
Intraarticular distal humerus fracture (ORIF)Olecranon osteotomy (best articular exposure)
Total elbow arthroplastyBryan-Morrey (extensile, triceps-sparing)
Distal humeral non-unionOlecranon osteotomy or Bryan-Morrey
Elbow contracture releaseParatricipital or triceps splitting
Olecranon fracture fixationDirect posterior (minimal approach)
Elbow arthroscopy (posterior portals)Direct posterior portal

Key Teaching Points (Exam Essentials)

  1. No internervous plane - the posterior approach deals with the triceps mechanism directly
  2. Ulnar nerve must always be identified and protected in every posterior variant
  3. Olecranon osteotomy = maximum articular exposure (Wilkinson & Stanley) but requires fixation
  4. Chevron osteotomy preferred over transverse - better stability, easier fixation
  5. Bare zone = the non-articular isthmus of olecranon ~2 cm from tip - safest site for osteotomy
  6. Bryan-Morrey key: periosteum + fascia reflected as ONE unit; weakest point is the medial junction - keep elbow extended 20-30° to protect this
  7. Radial nerve limits proximal extension along the humerus in all posterior approaches
  8. In TBE (total elbow): transpose ulnar nerve anteriorly to prevent stretch injury

Campbell's Operative Orthopaedics 15th Ed 2026, pp. 133-135; Miller's Review of Orthopaedics 9th Ed, p. 171

Create a detailed PDF surgical guide for posterior approaches with operative flowcharts

Reading File
Running Command

mkdir -p /home/daytona/workspace/elbow-surgical-guide && ls /home/daytona/worksp…

Writing File

~/elbow-surgical-guide/generate_guide.py

#!/usr/bin/env python3
"""
Posterior Approach to the Elbow - Detailed Surgical PDF Guide
Generated using ReportLab
"""

import urllib.request
import os
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    PageBreak, HRFlowable, Image, KeepTogether
)
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Polygon, Arrow
from reportlab.graphics.charts.flowchart import (
    FlowChart
)
from reportlab.graphics import renderPDF
from reportlab.lib.colors import HexColor, white, black
from io import BytesIO

# ─── COLORS ──────────────────────────────────────────────────────────────────
DARK_BLUE   = HexColor("#1A3A5C")
MED_BLUE    = HexColor("#2E6DA4")
LIGHT_BLUE  = HexColor("#D6E8F7")
ACCENT_RED  = HexColor("#C0392B")
ACCENT_GOLD = HexColor("#D4A017")
LIGHT_GRAY  = HexColor("#F4F6F8")
MED_GRAY    = HexColor("#BDC3C7")
DARK_GRAY   = HexColor("#2C3E50")
GREEN       = HexColor("#1E8449")
LIGHT_GREEN = HexColor("#D5F5E3")
ORANGE      = HexColor("#E67E22")
LIGHT_ORANGE= HexColor("#FDEBD0")
PURPLE      = HexColor("#6C3483")
LIGHT_PURPLE= HexColor("#E8DAEF")

OUTPUT_DIR  = "/home/daytona/workspace/elbow-surgical-guide"
OUTPUT_FILE = os.path.join(OUTPUT_DIR, "Posterior_Approach_Elbow_Surgical_Guide.pdf")

# ─── IMAGE URLS ──────────────────────────────────────────────────────────────
IMAGE_URLS = {
    "fig_superficial_deep": "https://cdn.orris.care/cdss_images/2477dc4444de168dfbb21c1e87ae6eb3d5a3a787def2fe08a24619f0b8eaa291.png",
    "fig_wadsworth":        "https://cdn.orris.care/cdss_images/81fe72680b1cea6e9254a59cac3bf1120470b50c601a493f523ad081caa236bd.png",
    "fig_osteotomy":        "https://cdn.orris.care/cdss_images/f75b33e45927a8639dac7a11b3255a6352d3b18cb3c8bff00cbce4fe077138dd.png",
    "fig_bryan_A":          "https://cdn.orris.care/cdss_images/b0dbc3251824c856d7b480e4ed9cfe9d2eb6512cd6f2a1bfa108875ea682b5e9.png",
    "fig_bryan_B":          "https://cdn.orris.care/cdss_images/754162cec53c2d11d4028343ba03246214da70d9bd9641686ea2dc15526f4365.png",
    "fig_bryan_C":          "https://cdn.orris.care/cdss_images/ae89d2832db6e229cbd38e2e90f7b04e94b61a53df6051e8fc3f9bddba0b5468.png",
}

def download_images():
    paths = {}
    for key, url in IMAGE_URLS.items():
        dest = os.path.join(OUTPUT_DIR, f"{key}.png")
        if not os.path.exists(dest):
            try:
                urllib.request.urlretrieve(url, dest)
                print(f"Downloaded {key}")
            except Exception as e:
                print(f"Failed to download {key}: {e}")
                dest = None
        paths[key] = dest
    return paths

# ─── STYLES ──────────────────────────────────────────────────────────────────
def make_styles():
    base = getSampleStyleSheet()

    styles = {}

    styles["cover_title"] = ParagraphStyle(
        "cover_title",
        fontName="Helvetica-Bold",
        fontSize=28,
        textColor=white,
        leading=34,
        alignment=TA_CENTER,
        spaceAfter=8,
    )
    styles["cover_subtitle"] = ParagraphStyle(
        "cover_subtitle",
        fontName="Helvetica",
        fontSize=14,
        textColor=HexColor("#B3D4F0"),
        leading=20,
        alignment=TA_CENTER,
        spaceAfter=4,
    )
    styles["cover_meta"] = ParagraphStyle(
        "cover_meta",
        fontName="Helvetica",
        fontSize=11,
        textColor=HexColor("#E0EAF4"),
        leading=16,
        alignment=TA_CENTER,
    )
    styles["section_header"] = ParagraphStyle(
        "section_header",
        fontName="Helvetica-Bold",
        fontSize=15,
        textColor=white,
        leading=20,
        spaceBefore=4,
        spaceAfter=4,
        leftIndent=0,
    )
    styles["subsection_header"] = ParagraphStyle(
        "subsection_header",
        fontName="Helvetica-Bold",
        fontSize=12,
        textColor=DARK_BLUE,
        leading=16,
        spaceBefore=10,
        spaceAfter=4,
        borderPad=2,
    )
    styles["body"] = ParagraphStyle(
        "body",
        fontName="Helvetica",
        fontSize=9.5,
        textColor=DARK_GRAY,
        leading=14,
        spaceAfter=5,
        alignment=TA_JUSTIFY,
    )
    styles["body_bold"] = ParagraphStyle(
        "body_bold",
        fontName="Helvetica-Bold",
        fontSize=9.5,
        textColor=DARK_GRAY,
        leading=14,
        spaceAfter=4,
    )
    styles["bullet"] = ParagraphStyle(
        "bullet",
        fontName="Helvetica",
        fontSize=9.5,
        textColor=DARK_GRAY,
        leading=14,
        leftIndent=14,
        spaceAfter=3,
    )
    styles["numbered"] = ParagraphStyle(
        "numbered",
        fontName="Helvetica",
        fontSize=9.5,
        textColor=DARK_GRAY,
        leading=14,
        leftIndent=18,
        firstLineIndent=-18,
        spaceAfter=4,
        alignment=TA_JUSTIFY,
    )
    styles["caption"] = ParagraphStyle(
        "caption",
        fontName="Helvetica-Oblique",
        fontSize=8.5,
        textColor=HexColor("#555555"),
        leading=12,
        alignment=TA_CENTER,
        spaceAfter=8,
    )
    styles["warning"] = ParagraphStyle(
        "warning",
        fontName="Helvetica-Bold",
        fontSize=9.5,
        textColor=ACCENT_RED,
        leading=14,
        leftIndent=10,
        spaceAfter=3,
    )
    styles["tip"] = ParagraphStyle(
        "tip",
        fontName="Helvetica-Oblique",
        fontSize=9,
        textColor=GREEN,
        leading=13,
        leftIndent=10,
        spaceAfter=3,
    )
    styles["flowchart_title"] = ParagraphStyle(
        "flowchart_title",
        fontName="Helvetica-Bold",
        fontSize=11,
        textColor=DARK_BLUE,
        leading=15,
        alignment=TA_CENTER,
        spaceAfter=6,
    )
    styles["toc_title"] = ParagraphStyle(
        "toc_title",
        fontName="Helvetica-Bold",
        fontSize=13,
        textColor=DARK_BLUE,
        leading=18,
        spaceAfter=8,
        alignment=TA_CENTER,
    )
    styles["toc_entry"] = ParagraphStyle(
        "toc_entry",
        fontName="Helvetica",
        fontSize=10,
        textColor=DARK_GRAY,
        leading=16,
        leftIndent=20,
        spaceAfter=2,
    )
    styles["toc_entry_bold"] = ParagraphStyle(
        "toc_entry_bold",
        fontName="Helvetica-Bold",
        fontSize=10,
        textColor=DARK_BLUE,
        leading=16,
        spaceAfter=2,
    )
    styles["page_header"] = ParagraphStyle(
        "page_header",
        fontName="Helvetica-Bold",
        fontSize=8,
        textColor=MED_BLUE,
        leading=10,
        alignment=TA_CENTER,
    )
    return styles

# ─── HELPER FLOWCHART DRAWING ─────────────────────────────────────────────────
def make_decision_flowchart():
    """Draws the main decision flowchart for selecting posterior approach variant."""
    W, H = 480, 420
    d = Drawing(W, H)

    # Background
    d.add(Rect(0, 0, W, H, fillColor=HexColor("#F7FBFF"), strokeColor=MED_BLUE, strokeWidth=1))

    def box(x, y, w, h, text, fill=LIGHT_BLUE, stroke=MED_BLUE, fontsize=8.5, bold=False, textcolor=DARK_GRAY, radius=4):
        d.add(Rect(x, y, w, h, rx=radius, ry=radius, fillColor=fill, strokeColor=stroke, strokeWidth=1.5))
        fn = "Helvetica-Bold" if bold else "Helvetica"
        # Simple centered text (multi-line via newline approximation)
        lines = text.split("\n")
        line_h = fontsize + 2
        total_h = len(lines) * line_h
        start_y = y + h/2 + total_h/2 - line_h
        for i, line in enumerate(lines):
            d.add(String(x + w/2, start_y - i*line_h, line,
                         fontName=fn, fontSize=fontsize,
                         fillColor=textcolor, textAnchor="middle"))

    def diamond(cx, cy, hw, hh, text, fill=LIGHT_ORANGE, stroke=ORANGE, fontsize=8):
        pts = [cx, cy+hh, cx+hw, cy, cx, cy-hh, cx-hw, cy]
        d.add(Polygon(pts, fillColor=fill, strokeColor=stroke, strokeWidth=1.5))
        lines = text.split("\n")
        line_h = fontsize + 2
        total_h = len(lines) * line_h
        for i, line in enumerate(lines):
            d.add(String(cx, cy + total_h/2 - fontsize/2 - i*line_h, line,
                         fontName="Helvetica-Bold", fontSize=fontsize,
                         fillColor=DARK_GRAY, textAnchor="middle"))

    def arrow(x1, y1, x2, y2):
        d.add(Line(x1, y1, x2, y2, strokeColor=DARK_GRAY, strokeWidth=1.2))
        # arrowhead
        if y2 < y1:
            d.add(Polygon([x2-5, y2+8, x2+5, y2+8, x2, y2],
                          fillColor=DARK_GRAY, strokeColor=DARK_GRAY, strokeWidth=0))
        elif y2 > y1:
            d.add(Polygon([x2-5, y2-8, x2+5, y2-8, x2, y2],
                          fillColor=DARK_GRAY, strokeColor=DARK_GRAY, strokeWidth=0))
        elif x2 > x1:
            d.add(Polygon([x2-8, y2-5, x2-8, y2+5, x2, y2],
                          fillColor=DARK_GRAY, strokeColor=DARK_GRAY, strokeWidth=0))
        elif x2 < x1:
            d.add(Polygon([x2+8, y2-5, x2+8, y2+5, x2, y2],
                          fillColor=DARK_GRAY, strokeColor=DARK_GRAY, strokeWidth=0))

    def label(x, y, text, fontsize=8, color=DARK_GRAY):
        d.add(String(x, y, text, fontName="Helvetica-Bold", fontSize=fontsize,
                     fillColor=color, textAnchor="middle"))

    # START box
    box(175, 380, 130, 30, "POSTERIOR APPROACH\nTO ELBOW",
        fill=DARK_BLUE, stroke=DARK_BLUE, bold=True, textcolor=white, fontsize=9)

    arrow(240, 380, 240, 340)

    # Decision diamond
    diamond(240, 310, 110, 35, "Surgical Indication?")

    # Left branch: intraarticular fracture
    arrow(130, 310, 75, 310)
    label(102, 318, "Intra-articular\nfracture / ORIF", 7.5)
    box(10, 280, 130, 45, "OLECRANON\nOSTEOTOMY\n(MacAusland & Muller)",
        fill=LIGHT_BLUE, stroke=MED_BLUE, bold=True, fontsize=8)

    # Right branch: arthroplasty/soft tissue
    arrow(350, 310, 405, 310)
    label(377, 318, "Arthroplasty /\nSoft tissue", 7.5)
    box(340, 280, 130, 45, "EXTENSILE\n(BRYAN-MORREY)\nTriceps-Sparing",
        fill=LIGHT_GREEN, stroke=GREEN, bold=True, fontsize=8)

    # Middle branch: contracture/limited
    arrow(240, 275, 240, 240)
    label(255, 260, "Contracture /\nLimited exposure", 7.5)
    box(160, 210, 160, 35, "TRICEPS SPLITTING\nor PARATRICIPITAL\n(Triceps Slide)",
        fill=LIGHT_PURPLE, stroke=PURPLE, bold=True, fontsize=8)

    # Sub-steps for Olecranon Osteotomy
    box(10, 215, 130, 55, "1. Identify bare zone\n2. Chevron cut (60°)\n3. Fracture last 1/4\n4. Reflect + fix",
        fill=HexColor("#EAF4FB"), stroke=MED_BLUE, fontsize=7.5)
    arrow(75, 280, 75, 270)

    # Sub-steps for Bryan-Morrey
    box(340, 215, 130, 55, "1. Identify ulnar nerve\n2. Elevate triceps medial\n3. Reflect fascia unit\n4. Reflect anconeus",
        fill=HexColor("#EAFAF1"), stroke=GREEN, fontsize=7.5)
    arrow(405, 280, 405, 270)

    # Ulnar Nerve WARNING box
    box(135, 130, 210, 35, "! ULNAR NERVE !\nMust be identified &\nprotected in ALL variants",
        fill=HexColor("#FDEDEC"), stroke=ACCENT_RED, bold=True, textcolor=ACCENT_RED, fontsize=8)
    arrow(240, 210, 240, 165)

    # Closure
    box(155, 65, 170, 40, "CLOSURE\nRepair triceps via transosseous\nsutures. MCL if released.",
        fill=HexColor("#FEF9E7"), stroke=ACCENT_GOLD, fontsize=7.5)
    arrow(240, 130, 240, 105)

    # Rehab
    box(165, 10, 150, 40, "REHABILITATION\nBryan-Morrey: 60° dressing\nOsteotomy: TBW/lag screw",
        fill=LIGHT_GRAY, stroke=MED_GRAY, fontsize=7.5)
    arrow(240, 65, 240, 50)

    return d


def make_nerve_risk_diagram():
    """Compact diagram showing structures at risk."""
    W, H = 460, 200
    d = Drawing(W, H)
    d.add(Rect(0, 0, W, H, fillColor=HexColor("#FFFAF0"), strokeColor=ACCENT_GOLD, strokeWidth=1))

    title_y = 183
    d.add(String(W/2, title_y, "Structures at Risk in Posterior Approach",
                 fontName="Helvetica-Bold", fontSize=10, fillColor=DARK_BLUE, textAnchor="middle"))

    entries = [
        ("Ulnar Nerve", "Most common injury; runs in cubital tunnel behind medial epicondyle;\nmust be identified and retracted with Penrose drain", ACCENT_RED, 140),
        ("Radial Nerve", "Limits proximal extension; courses anterolaterally at spiral groove;\ndo not extend approach too proximally", ORANGE, 85),
        ("Articular Cartilage", "Saw kerf during osteotomy destroys articular surface;\nalways fracture final 1/4 with osteotome only", MED_BLUE, 30),
    ]

    for title, desc, col, y_pos in entries:
        d.add(Rect(10, y_pos, 440, 46, rx=4, ry=4,
                   fillColor=HexColor("#FFFAF0"), strokeColor=col, strokeWidth=1.5))
        d.add(String(18, y_pos + 32, title,
                     fontName="Helvetica-Bold", fontSize=9, fillColor=col, textAnchor="start"))
        lines = desc.split("\n")
        for i, line in enumerate(lines):
            d.add(String(18, y_pos + 18 - i*12, line,
                         fontName="Helvetica", fontSize=8, fillColor=DARK_GRAY, textAnchor="start"))

    return d


def make_osteotomy_steps_diagram():
    """Visual steps for chevron osteotomy."""
    W, H = 460, 100
    d = Drawing(W, H)
    d.add(Rect(0, 0, W, H, fillColor=LIGHT_BLUE, strokeColor=MED_BLUE, strokeWidth=1))

    steps = [
        ("Step 1", "Pre-drill\nfixation hole\n(6.5mm screw)", MED_BLUE),
        ("Step 2", "Mark bare zone\n(~2cm from tip)\nK-wire at apex", DARK_BLUE),
        ("Step 3", "Chevron cut\n60° with thin\noscillating saw\n(3/4 depth only)", ORANGE),
        ("Step 4", "Fracture last\n1/4 with\nosteotome\n(protect cartilage)", ACCENT_RED),
        ("Step 5", "Reflect olecranon\nproximal with\ntriceps attached", GREEN),
        ("Step 6", "Reduce & fix:\nLag screw +\nTension band\nwire (TBW)", PURPLE),
    ]

    col_w = W / len(steps)
    for i, (title, desc, col) in enumerate(steps):
        x = i * col_w + 4
        d.add(Rect(x, 8, col_w - 8, 88, rx=4, ry=4,
                   fillColor=white, strokeColor=col, strokeWidth=1.5))
        d.add(String(x + (col_w-8)/2, 83, title,
                     fontName="Helvetica-Bold", fontSize=8, fillColor=col, textAnchor="middle"))
        lines = desc.split("\n")
        for j, line in enumerate(lines):
            d.add(String(x + (col_w-8)/2, 68 - j*12, line,
                         fontName="Helvetica", fontSize=7.5, fillColor=DARK_GRAY, textAnchor="middle"))
        if i < len(steps)-1:
            ax = x + col_w - 6
            d.add(Line(ax, 52, ax+4, 52, strokeColor=MED_GRAY, strokeWidth=1))
            d.add(Polygon([ax+4, 56, ax+4, 48, ax+9, 52],
                          fillColor=MED_GRAY, strokeColor=MED_GRAY, strokeWidth=0))

    return d


def make_bryan_morrey_steps():
    """Visual steps for Bryan-Morrey approach."""
    W, H = 460, 100
    d = Drawing(W, H)
    d.add(Rect(0, 0, W, H, fillColor=LIGHT_GREEN, strokeColor=GREEN, strokeWidth=1))

    steps = [
        ("Step 1", "Lateral decubitus\nposition; arm\nacross chest", GREEN),
        ("Step 2", "Posterior midline\nincision 7cm distal\nto 9cm proximal\nolecranon tip", MED_BLUE),
        ("Step 3", "Identify ulnar\nnerve at medial\ntriceps border;\ntranspose anteriorly\n(in TEA)", ACCENT_RED),
        ("Step 4", "Elevate medial\ntriceps from\nhumerus along\nintermuscular\nseptum", ORANGE),
        ("Step 5", "Reflect periosteum\n+ fascia as ONE\nunit medial to\nlateral; extend\nelbow 20-30°", PURPLE),
        ("Step 6", "Reflect anconeus;\njoint exposed;\nclosure: transosseous\nsutures for triceps", DARK_BLUE),
    ]

    col_w = W / len(steps)
    for i, (title, desc, col) in enumerate(steps):
        x = i * col_w + 4
        d.add(Rect(x, 8, col_w - 8, 88, rx=4, ry=4,
                   fillColor=white, strokeColor=col, strokeWidth=1.5))
        d.add(String(x + (col_w-8)/2, 83, title,
                     fontName="Helvetica-Bold", fontSize=8, fillColor=col, textAnchor="middle"))
        lines = desc.split("\n")
        for j, line in enumerate(lines):
            d.add(String(x + (col_w-8)/2, 68 - j*11, line,
                         fontName="Helvetica", fontSize=7.5, fillColor=DARK_GRAY, textAnchor="middle"))
        if i < len(steps)-1:
            ax = x + col_w - 6
            d.add(Line(ax, 52, ax+4, 52, strokeColor=MED_GRAY, strokeWidth=1))
            d.add(Polygon([ax+4, 56, ax+4, 48, ax+9, 52],
                          fillColor=MED_GRAY, strokeColor=MED_GRAY, strokeWidth=0))

    return d


# ─── PAGE CALLBACKS ──────────────────────────────────────────────────────────
def cover_background(canvas, doc):
    """Draw cover page background gradient."""
    canvas.saveState()
    # Gradient effect via rectangles
    for i in range(100):
        frac = i / 100.0
        r = 0.1 + frac * 0.08
        g = 0.22 + frac * 0.06
        b = 0.36 + frac * 0.10
        canvas.setFillColorRGB(r, g, b)
        canvas.rect(0, doc.height - i * (doc.height/100),
                    doc.width + doc.leftMargin + doc.rightMargin,
                    doc.height/100 + 2, fill=1, stroke=0)

    # Decorative bar top
    canvas.setFillColor(HexColor("#1A6B9A"))
    canvas.rect(0, doc.height + doc.topMargin - 18,
                doc.width + doc.leftMargin + doc.rightMargin, 18, fill=1, stroke=0)

    # Decorative bar bottom
    canvas.setFillColor(ACCENT_GOLD)
    canvas.rect(0, 0,
                doc.width + doc.leftMargin + doc.rightMargin, 8, fill=1, stroke=0)

    canvas.restoreState()


def regular_page(canvas, doc):
    """Header and footer for regular pages."""
    canvas.saveState()
    W = doc.width + doc.leftMargin + doc.rightMargin

    # Header bar
    canvas.setFillColor(DARK_BLUE)
    canvas.rect(0, doc.height + doc.topMargin - 22, W, 22, fill=1, stroke=0)
    canvas.setFillColor(white)
    canvas.setFont("Helvetica-Bold", 8)
    canvas.drawCentredString(W/2, doc.height + doc.topMargin - 14,
                             "POSTERIOR APPROACH TO THE ELBOW  |  Surgical Guide")

    # Gold accent line under header
    canvas.setFillColor(ACCENT_GOLD)
    canvas.rect(0, doc.height + doc.topMargin - 24, W, 2, fill=1, stroke=0)

    # Footer
    canvas.setFillColor(LIGHT_GRAY)
    canvas.rect(0, 0, W, 20, fill=1, stroke=0)
    canvas.setFillColor(MED_GRAY)
    canvas.rect(0, 19, W, 1, fill=1, stroke=0)
    canvas.setFillColor(DARK_GRAY)
    canvas.setFont("Helvetica", 7.5)
    canvas.drawCentredString(W/2, 6,
        f"Source: Campbell's Operative Orthopaedics 15th Ed (2026) | Miller's Review of Orthopaedics 9th Ed  |  Page {doc.page}")
    canvas.restoreState()


# ─── SECTION HEADER HELPER ───────────────────────────────────────────────────
def section_header(title, styles, bg_color=None, icon=""):
    if bg_color is None:
        bg_color = DARK_BLUE
    data = [[Paragraph(f"{icon} {title}", styles["section_header"])]]
    t = Table(data, colWidths=[16.5*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg_color),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("TOPPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING", (0,0), (-1,-1), 12),
        ("RIGHTPADDING", (0,0), (-1,-1), 8),
        ("ROUNDEDCORNERS", [4, 4, 4, 4]),
    ]))
    return t


def info_box(items, styles, color=LIGHT_BLUE, border=MED_BLUE, label=""):
    """A simple colored information box."""
    content = []
    if label:
        content.append(Paragraph(f"<b>{label}</b>", styles["body_bold"]))
    for item in items:
        content.append(Paragraph(f"• {item}", styles["bullet"]))
    data = [[content]]
    t = Table(data, colWidths=[16.5*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), color),
        ("BOX", (0,0), (-1,-1), 1.5, border),
        ("TOPPADDING", (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING", (0,0), (-1,-1), 12),
        ("RIGHTPADDING", (0,0), (-1,-1), 8),
    ]))
    return t


def warning_box(items, styles):
    content = [Paragraph("⚠  STRUCTURES AT RISK / COMPLICATIONS", styles["warning"])]
    for item in items:
        content.append(Paragraph(f"▶ {item}", styles["warning"]))
    data = [[content]]
    t = Table(data, colWidths=[16.5*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), HexColor("#FDEDEC")),
        ("BOX", (0,0), (-1,-1), 2, ACCENT_RED),
        ("TOPPADDING", (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING", (0,0), (-1,-1), 10),
        ("RIGHTPADDING", (0,0), (-1,-1), 8),
    ]))
    return t


def tip_box(items, styles):
    content = [Paragraph("✔  SURGICAL PEARLS", styles["tip"])]
    for item in items:
        content.append(Paragraph(f"✓ {item}", styles["tip"]))
    data = [[content]]
    t = Table(data, colWidths=[16.5*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), LIGHT_GREEN),
        ("BOX", (0,0), (-1,-1), 1.5, GREEN),
        ("TOPPADDING", (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING", (0,0), (-1,-1), 10),
        ("RIGHTPADDING", (0,0), (-1,-1), 8),
    ]))
    return t


def safe_image(path, width, caption=None, styles=None):
    """Return Image + optional caption, or fallback text if image missing."""
    elems = []
    if path and os.path.exists(path):
        try:
            img = Image(path, width=width)
            img.hAlign = "CENTER"
            elems.append(img)
        except Exception:
            elems.append(Spacer(1, 0.3*cm))
    else:
        elems.append(Spacer(1, 0.3*cm))
    if caption and styles:
        elems.append(Paragraph(caption, styles["caption"]))
    return elems


# ─── BUILD PDF ────────────────────────────────────────────────────────────────
def build_pdf(img_paths):
    styles = make_styles()

    doc = SimpleDocTemplate(
        OUTPUT_FILE,
        pagesize=A4,
        leftMargin=2*cm, rightMargin=2*cm,
        topMargin=2.5*cm, bottomMargin=1.8*cm,
        title="Posterior Approach to the Elbow - Surgical Guide",
        author="Orris Medical AI",
        subject="Orthopaedic Surgery",
    )

    story = []

    # ══════════════════════════════════════════════════════════════════════════
    # COVER PAGE
    # ══════════════════════════════════════════════════════════════════════════
    cover_data = [
        [Paragraph("POSTERIOR APPROACH<br/>TO THE ELBOW", styles["cover_title"])],
        [Spacer(1, 0.5*cm)],
        [Paragraph("A Comprehensive Operative Surgical Guide", styles["cover_subtitle"])],
        [Spacer(1, 0.3*cm)],
        [Paragraph("Including Variants, Operative Flowcharts,<br/>Anatomical Landmarks & Clinical Pearls", styles["cover_meta"])],
        [Spacer(1, 0.8*cm)],
        [Paragraph("─────────────────────────────────", styles["cover_meta"])],
        [Spacer(1, 0.4*cm)],
        [Paragraph("Approach Variants Covered:", styles["cover_meta"])],
        [Spacer(1, 0.2*cm)],
        [Paragraph("1. Olecranon Osteotomy (MacAusland &amp; Müller)<br/>"
                   "2. Extensile Posterior - Bryan-Morrey (Triceps-Sparing)<br/>"
                   "3. Triceps Splitting<br/>"
                   "4. Paratricipital (Triceps Slide)", styles["cover_meta"])],
        [Spacer(1, 0.8*cm)],
        [Paragraph("─────────────────────────────────", styles["cover_meta"])],
        [Spacer(1, 0.3*cm)],
        [Paragraph("Source: Campbell's Operative Orthopaedics 15th Ed (2026)<br/>"
                   "Miller's Review of Orthopaedics 9th Edition", styles["cover_meta"])],
        [Spacer(1, 0.3*cm)],
        [Paragraph("Compiled by Orris Medical AI  |  July 2026", styles["cover_meta"])],
    ]

    for row in cover_data:
        story.append(row[0])

    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # TABLE OF CONTENTS
    # ══════════════════════════════════════════════════════════════════════════
    story.append(Paragraph("TABLE OF CONTENTS", styles["toc_title"]))
    story.append(HRFlowable(width="100%", thickness=2, color=MED_BLUE))
    story.append(Spacer(1, 0.3*cm))

    toc_entries = [
        ("1.", "Surgical Anatomy & Overview", True),
        ("", "   Osseous anatomy, soft tissue landmarks, neurovascular", False),
        ("2.", "Decision Flowchart - Selecting the Approach Variant", True),
        ("3.", "Approach Variant 1: Olecranon Osteotomy (MacAusland & Müller)", True),
        ("", "   Indications, position, incision, steps, fixation", False),
        ("4.", "Approach Variant 2: Extensile Posterior (Bryan-Morrey)", True),
        ("", "   Indications, position, steps, triceps reflection, closure", False),
        ("5.", "Approach Variants 3 & 4: Triceps Splitting / Paratricipital", True),
        ("6.", "Structures at Risk & Complications", True),
        ("7.", "Indications Quick Reference", True),
        ("8.", "Examination Key Points (10-mark answer summary)", True),
    ]

    for num, text, bold in toc_entries:
        style = styles["toc_entry_bold"] if bold else styles["toc_entry"]
        story.append(Paragraph(f"{num}  {text}", style))

    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 1: SURGICAL ANATOMY
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("1. SURGICAL ANATOMY & OVERVIEW", styles))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph(
        "The posterior approach is the primary workhorse approach to the elbow joint. "
        "It provides excellent access to the distal humerus, trochlea, capitellum, olecranon, "
        "radial head, and the elbow joint capsule. A defining feature of this approach is that "
        "it has <b>no true internervous plane</b> - the triceps mechanism must be managed directly.",
        styles["body"]
    ))
    story.append(Spacer(1, 0.2*cm))

    # Anatomy table
    story.append(Paragraph("Key Anatomical Structures", styles["subsection_header"]))

    anat_data = [
        ["Structure", "Location", "Surgical Relevance"],
        ["Olecranon", "Proximal ulna; forms the 'point' of elbow", "Blocks direct articular access; may be osteotomized"],
        ["Triceps tendon", "Inserts onto olecranon tip", "Must be reflected, split, or detached for joint entry"],
        ["Ulnar nerve", "Runs behind medial epicondyle in cubital tunnel", "AT RISK in ALL variants - must be identified first"],
        ["Anconeus", "Small muscle posterolateral; radial nerve", "Lateral landmark; reflects subperiosteally for radial head"],
        ["Medial epicondyle", "Medial prominence of distal humerus", "Landmark for ulnar nerve; attached to MCL"],
        ["Bare zone (olecranon)", "Non-articular isthmus ~2 cm from tip", "Safest site for chevron osteotomy"],
        ["Radial nerve", "Spiral groove of humerus; continues as PIN", "Limits proximal extension; do not extend too far proximally"],
        ["MCL (medial collateral lig.)", "Medial joint; fan-shaped", "May need release for joint subluxation in TEA; repair at closure"],
        ["Posterior capsule", "Posterior joint", "Usually reflects with triceps in Bryan-Morrey approach"],
    ]

    anat_table = Table(anat_data, colWidths=[3.8*cm, 5.5*cm, 7.2*cm])
    anat_table.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
        ("TEXTCOLOR", (0,0), (-1,0), white),
        ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE", (0,0), (-1,0), 9),
        ("ALIGN", (0,0), (-1,-1), "LEFT"),
        ("FONTNAME", (0,1), (-1,-1), "Helvetica"),
        ("FONTSIZE", (0,1), (-1,-1), 8.5),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [white, LIGHT_BLUE]),
        ("GRID", (0,0), (-1,-1), 0.5, MED_GRAY),
        ("TOPPADDING", (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING", (0,0), (-1,-1), 6),
        ("BACKGROUND", (0,3), (-1,3), HexColor("#FDECEA")),
        ("TEXTCOLOR", (1,3), (1,3), ACCENT_RED),
    ]))
    story.append(anat_table)
    story.append(Spacer(1, 0.4*cm))

    story.append(Paragraph("Patient Positioning Principles", styles["subsection_header"]))
    story.append(info_box([
        "Lateral decubitus OR prone position with arm supported on a padded arm board",
        "Elbow flexed 90° over the arm support for prone; arm placed across chest for lateral decubitus",
        "Tourniquet applied to proximal arm (inflate to 250-300 mmHg)",
        "Avoid compression of ulnar nerve at elbow from positioning",
        "Ensure free access to posterior elbow throughout ROM",
    ], styles, color=LIGHT_BLUE, label="Positioning"))
    story.append(Spacer(1, 0.3*cm))

    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 2: DECISION FLOWCHART
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("2. DECISION FLOWCHART - SELECTING THE APPROACH VARIANT", styles, bg_color=MED_BLUE))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph(
        "The choice of posterior approach variant depends on the primary surgical indication, "
        "requirement for articular exposure, and the need to preserve the triceps mechanism. "
        "The flowchart below guides the selection process.",
        styles["body"]
    ))
    story.append(Spacer(1, 0.3*cm))

    story.append(make_decision_flowchart())
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph(
        "Figure 1. Decision flowchart for selecting the appropriate posterior approach to the elbow. "
        "Note that the ulnar nerve must be identified and protected in ALL variants.",
        styles["caption"]
    ))
    story.append(Spacer(1, 0.4*cm))

    # Variant comparison table
    story.append(Paragraph("Comparison of Posterior Approach Variants", styles["subsection_header"]))
    comp_data = [
        ["Variant", "Triceps Handling", "Articular Exposure", "Best Indication", "Key Risk"],
        ["Olecranon Osteotomy", "Reflected with osteotomy fragment", "MAXIMUM\n(>70% articular)", "Intraarticular ORIF\nDistal humerus fractures", "Non-union / malunion\nof osteotomy"],
        ["Bryan-Morrey\n(Extensile)", "Reflected as one unit\nmedial to lateral", "Excellent\n(whole joint)", "Total elbow arthroplasty\nElbow arthroplasty", "Triceps avulsion if\ncontinuity disrupted"],
        ["Triceps Splitting", "Split in midline;\nolecranon intact", "Moderate", "Limited access,\ncontracture release", "Weak repair if\npoor tissue"],
        ["Paratricipital\n(Triceps Slide)", "Elevated off intermuscular\nsepta; insertion intact", "Moderate-Good\n(bilateral)", "Access without\ntriceps detachment", "Ulnar nerve;\nradial nerve proximally"],
    ]
    comp_table = Table(comp_data, colWidths=[3.3*cm, 3.8*cm, 2.8*cm, 3.5*cm, 3.1*cm])
    comp_table.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
        ("TEXTCOLOR", (0,0), (-1,0), white),
        ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE", (0,0), (-1,0), 8.5),
        ("FONTNAME", (0,1), (-1,-1), "Helvetica"),
        ("FONTSIZE", (0,1), (-1,-1), 8),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [white, LIGHT_GRAY]),
        ("GRID", (0,0), (-1,-1), 0.5, MED_GRAY),
        ("ALIGN", (0,0), (-1,-1), "CENTER"),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("TOPPADDING", (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("BACKGROUND", (2,1), (2,1), LIGHT_GREEN),
        ("TEXTCOLOR", (2,1), (2,1), GREEN),
        ("FONTNAME", (2,1), (2,1), "Helvetica-Bold"),
    ]))
    story.append(comp_table)
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 3: OLECRANON OSTEOTOMY
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("3. VARIANT 1 — OLECRANON OSTEOTOMY (MacAusland & Müller)", styles, bg_color=MED_BLUE))
    story.append(Spacer(1, 0.3*cm))

    story.append(info_box([
        "Best articular exposure of distal humerus (Wilkinson & Stanley: significantly more articular surface exposed vs triceps-reflecting approach)",
        "Intraarticular fractures of the distal humerus requiring ORIF",
        "Distal humeral non-union requiring revision fixation",
        "Complex elbow reconstruction where full articular visualization is needed",
    ], styles, color=LIGHT_BLUE, label="INDICATIONS"))
    story.append(Spacer(1, 0.25*cm))

    story.append(Paragraph("Operative Steps", styles["subsection_header"]))

    steps_ost = [
        ("1", "INCISION", "Begin 5 cm distal to the tip of the olecranon; extend proximally medial to the midline of the arm to 10-12 cm above the olecranon tip."),
        ("2", "SKIN FLAPS", "Reflect skin and subcutaneous tissue to either side to expose the olecranon and triceps tendon."),
        ("3", "ULNAR NERVE", "Identify the ulnar nerve in its groove behind the medial epicondyle. Retract gently with a Penrose drain or moist umbilical tape."),
        ("4", "PRE-DRILL", "Before the osteotomy, place the chosen fixation device (6.5mm cancellous screw, tension band wire, or plate) as a pre-drill step. This assists later reduction - the saw kerf and bone loss make accurate re-reduction challenging."),
        ("5", "BARE ZONE", "Identify the bare zone of the olecranon - the non-articular isthmus approximately 2 cm from the tip. Use direct visualization or fluoroscopic imaging. Place a Kirschner wire centrally at this point."),
        ("6", "CHEVRON MARK", "Mark a 60-degree chevron osteotomy with the apex pointing distally at the K-wire position. The chevron shape provides rotational stability and a larger surface area for healing vs a transverse cut."),
        ("7", "SAW CUT", "Divide THREE-QUARTERS of the depth with a thin oscillating saw. Do not complete the full cut - this protects the articular cartilage from saw kerf damage."),
        ("8", "OSTEOTOME COMPLETE", "Fracture the remaining one-quarter with an osteotome. This creates a rough cancellous surface which promotes healing and avoids saw kerf through articular cartilage."),
        ("9", "REFLECT", "Reflect the olecranon fragment and attached triceps proximally - full posterior and articular exposure is now achieved. Use a suture to hold the fragment proximally. Wrap articular surface in a moist laparotomy pad."),
        ("10", "CLOSURE - FIXATION", "After the intraarticular procedure: reduce the osteotomy fragment accurately, then fix with the pre-placed implant. Options: 6.5mm cancellous lag screw + tension band wire (standard), OR plate and screws, OR independent screws."),
    ]

    for num, title, detail in steps_ost:
        data_row = [[
            Paragraph(f"<b>{num}</b>", styles["body_bold"]),
            [Paragraph(f"<b>{title}</b>", styles["body_bold"]),
             Paragraph(detail, styles["body"])]
        ]]
        t = Table(data_row, colWidths=[0.8*cm, 15.7*cm])
        t.setStyle(TableStyle([
            ("ALIGN", (0,0), (0,0), "CENTER"),
            ("VALIGN", (0,0), (-1,-1), "TOP"),
            ("TOPPADDING", (0,0), (-1,-1), 4),
            ("BOTTOMPADDING", (0,0), (-1,-1), 2),
            ("LEFTPADDING", (0,0), (0,0), 2),
            ("LEFTPADDING", (1,0), (1,0), 6),
            ("ROWBACKGROUNDS", (0,0), (-1,-1),
             [LIGHT_BLUE if int(num)%2==0 else white]),
        ]))
        story.append(t)

    story.append(Spacer(1, 0.3*cm))

    # Osteotomy step diagram
    story.append(Paragraph("Operative Step Summary - Olecranon Osteotomy", styles["flowchart_title"]))
    story.append(make_osteotomy_steps_diagram())
    story.append(Paragraph(
        "Figure 2. Sequential steps of the chevron olecranon osteotomy.",
        styles["caption"]
    ))
    story.append(Spacer(1, 0.3*cm))

    # Images
    for path, cap in [
        (img_paths.get("fig_superficial_deep"),
         "Figure 3. Posterior approach to elbow. A: Superficial exposure showing olecranon osteotomy site and ulnar nerve. "
         "B: Deep exposure after osteotomy reflection, revealing the trochlea, periosteum, and olecranon."),
        (img_paths.get("fig_osteotomy"),
         "Figure 4. Olecranon osteotomy technique. A: Pre-drilling. B: Incomplete chevron osteotomy with K-wire. "
         "C: Osteotomy completed by fracturing. D: 6.5mm lag screw and tension band wire fixation."),
    ]:
        for elem in safe_image(path, 14*cm, cap, styles):
            story.append(elem)

    story.append(warning_box([
        "Ulnar nerve - identify before all other dissection; retract with Penrose drain",
        "Saw kerf - never complete osteotomy with saw; always fracture last 1/4 with osteotome",
        "Non-union of osteotomy - pre-drill helps but anatomic reduction at closure is essential",
        "Articular cartilage desiccation - always wrap exposed cartilage in moist pads",
    ], styles))
    story.append(Spacer(1, 0.2*cm))

    story.append(tip_box([
        "Pre-drill the fixation before the osteotomy - prevents difficult reduction later",
        "Chevron osteotomy is superior to transverse cut - rotational stability, better healing",
        "Fluoroscopy helps identify the bare zone; direct palpation can also be used",
        "A suture looped around the reflected fragment prevents it from flopping onto instruments",
    ], styles))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 4: BRYAN-MORREY
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("4. VARIANT 2 — EXTENSILE POSTERIOR (BRYAN-MORREY)", styles, bg_color=GREEN))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph(
        "Bryan and Morrey developed this modified posterior approach to provide excellent exposure "
        "while <b>preserving the continuity of the triceps mechanism</b>, allowing easy repair and "
        "rapid rehabilitation. This is the preferred approach for total elbow arthroplasty (TEA).",
        styles["body"]
    ))
    story.append(Spacer(1, 0.2*cm))

    story.append(info_box([
        "Total elbow arthroplasty (TEA) - primary indication",
        "Distal humeral non-union requiring elbow arthroplasty",
        "Revision elbow arthroplasty",
        "Situations where triceps continuity and rapid rehabilitation are priorities",
        "Elderly patients with poor bone quality (osteotomy fixation unreliable)",
    ], styles, color=LIGHT_GREEN, label="INDICATIONS"))
    story.append(Spacer(1, 0.25*cm))

    story.append(Paragraph("Operative Steps", styles["subsection_header"]))

    steps_bm = [
        ("1", "POSITION", "Place patient in lateral decubitus or tilted 45-60 degrees with sandbags under back and hip. Place the limb across the chest."),
        ("2", "INCISION", "Straight posterior midline incision from 7 cm distal to the tip of the olecranon to 9 cm proximal to it (total ~16 cm)."),
        ("3", "ULNAR NERVE IDENTIFICATION", "Find the ulnar nerve proximally at the medial border of the medial head of the triceps. Dissect it free from its tunnel distally to its first motor branch into the FCU. In total elbow arthroplasty: transpose the nerve anteriorly into subcutaneous tissue to prevent stretch injury."),
        ("4", "MEDIAL TRICEPS ELEVATION", "Elevate the medial aspect of the triceps from the humerus, dissecting along the intermuscular septum, down to the level of the posterior capsule."),
        ("5", "FOREARM FASCIA INCISION", "Incise the superficial fascia of the forearm distally for approximately 6 cm to the periosteum of the medial aspect of the olecranon."),
        ("6", "REFLECT AS ONE UNIT", "Carefully reflect periosteum + fascia as a SINGLE CONTINUOUS UNIT from medial to lateral. "
         "CRITICAL POINT: The medial junction of the triceps insertion, superficial fascia, and ulnar periosteum is the weakest point - "
         "keep this intact. Extend the elbow to 20-30 degrees during triceps dissection from olecranon to relieve tissue tension."),
        ("7", "ANCONEUS", "Reflect the anconeus subperiosteally from the proximal ulna to expose the radial head."),
        ("8", "FULL EXPOSURE", "The entire joint is now widely exposed. The posterior capsule usually elevates with the triceps mechanism. "
         "The tip of the olecranon may be resected to clearly expose the trochlea."),
        ("9", "MCL RELEASE (if needed)", "For total joint arthroplasty: release the medial collateral ligament from the humerus if needed for adequate joint retraction/dislocation."),
        ("10", "CLOSURE", "Carefully repair the MCL if it was released. Return triceps to anatomic position and suture through holes drilled in the proximal ulna (transosseous sutures). Suture periosteum to superficial forearm fascia up to the margin of the FCU. Drain the wound. Dress with elbow at 60° flexion in TEA."),
    ]

    for num, title, detail in steps_bm:
        data_row = [[
            Paragraph(f"<b>{num}</b>", styles["body_bold"]),
            [Paragraph(f"<b>{title}</b>", styles["body_bold"]),
             Paragraph(detail, styles["body"])]
        ]]
        bg = LIGHT_GREEN if int(num)%2==0 else white
        t = Table(data_row, colWidths=[0.8*cm, 15.7*cm])
        t.setStyle(TableStyle([
            ("ALIGN", (0,0), (0,0), "CENTER"),
            ("VALIGN", (0,0), (-1,-1), "TOP"),
            ("TOPPADDING", (0,0), (-1,-1), 4),
            ("BOTTOMPADDING", (0,0), (-1,-1), 2),
            ("LEFTPADDING", (0,0), (0,0), 2),
            ("LEFTPADDING", (1,0), (1,0), 6),
            ("ROWBACKGROUNDS", (0,0), (-1,-1), [bg]),
        ]))
        story.append(t)

    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph("Operative Step Summary - Bryan-Morrey Approach", styles["flowchart_title"]))
    story.append(make_bryan_morrey_steps())
    story.append(Paragraph(
        "Figure 5. Sequential steps of the Bryan-Morrey extensile posterior approach.",
        styles["caption"]
    ))
    story.append(Spacer(1, 0.2*cm))

    # Images
    for path, cap in [
        (img_paths.get("fig_wadsworth"),
         "Figure 6. Bryan-Morrey / Wadsworth posterolateral approach. "
         "A: Skin incision (curved paramedian) with patient prone, elbow flexed. "
         "B: Superficial layer - triceps tendon with ulnar nerve identified. "
         "C: Complete exposure showing capitellum, radius, anconeus, and extensor carpi ulnaris."),
        (img_paths.get("fig_bryan_A"),
         "Figure 7A. Bryan-Morrey approach - superficial exposure. "
         "Olecranon at top, superficial forearm fascia, and dashed green line indicating line of incision. "
         "Ulnar nerve and medial epicondyle are clearly labeled."),
        (img_paths.get("fig_bryan_B"),
         "Figure 7B. Bryan-Morrey approach - intermediate layer. "
         "Ulnar nerve retracted with vessel loop, triceps muscle elevated off medial epicondyle."),
        (img_paths.get("fig_bryan_C"),
         "Figure 7C. Bryan-Morrey approach - deep layer. "
         "Periosteum and forearm fascia reflected as one unit. Joint capsule, medial epicondyle, "
         "olecranon and FCU visible. Ulnar nerve (yellow vessel loop) protected laterally."),
    ]:
        for elem in safe_image(path, 13*cm, cap, styles):
            story.append(elem)

    story.append(warning_box([
        "Triceps avulsion - highest risk at the medial junction of triceps insertion/fascia/periosteum; keep as ONE unit",
        "Ulnar nerve injury - most common complication; always identify and transpose in TEA",
        "Do NOT divide triceps transversely - destroys the mechanism",
        "MCL repair at closure is mandatory if it was released",
        "Radial nerve limits proximal extension along humerus",
    ], styles))
    story.append(Spacer(1, 0.2*cm))

    story.append(tip_box([
        "KEY PEARL: Extend elbow 20-30° while dissecting triceps off olecranon - reduces tension at weakest point",
        "Anterior transposition of ulnar nerve prevents stretch injury during TEA manipulation",
        "Use a periosteal elevator rather than sharp dissection at the medial junction",
        "Wrap the articular surface if exposing the joint for extended periods",
        "In TEA: dress with 60° elbow flexion to prevent direct pressure on wound from olecranon",
    ], styles))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 5: TRICEPS SPLITTING & PARATRICIPITAL
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("5. VARIANTS 3 & 4 — TRICEPS SPLITTING / PARATRICIPITAL", styles, bg_color=PURPLE))
    story.append(Spacer(1, 0.3*cm))

    col_data = [
        [
            [
                Paragraph("Triceps Splitting", styles["subsection_header"]),
                Paragraph("<b>Interval:</b> Midline split of the triceps muscle and tendon, leaving the olecranon intact.", styles["body"]),
                Paragraph("<b>Dissection:</b>", styles["body_bold"]),
                Paragraph("• Posterior midline incision", styles["bullet"]),
                Paragraph("• Identify and protect ulnar nerve", styles["bullet"]),
                Paragraph("• Split triceps in midline from proximal to its insertion", styles["bullet"]),
                Paragraph("• Reflect each half laterally for exposure", styles["bullet"]),
                Paragraph("• Olecranon remains intact throughout", styles["bullet"]),
                Spacer(1, 0.2*cm),
                Paragraph("<b>Indications:</b> Limited access, elbow contracture release, simple distal humeral procedures where full articular exposure not needed.", styles["body"]),
                Spacer(1, 0.2*cm),
                Paragraph("<b>Advantage:</b> No osteotomy required, simpler closure.", styles["body"]),
                Paragraph("<b>Limitation:</b> Moderate articular exposure, triceps repair may be weak in poor tissue.", styles["body"]),
            ],
            [
                Paragraph("Paratricipital (Triceps Slide)", styles["subsection_header"]),
                Paragraph("<b>Interval:</b> The triceps is elevated off the medial AND lateral intermuscular septa, allowing the tendon to be mobilized in either direction. The triceps insertion onto the olecranon remains <b>completely undisturbed</b>.", styles["body"]),
                Paragraph("<b>Dissection:</b>", styles["body_bold"]),
                Paragraph("• Posterior midline incision", styles["bullet"]),
                Paragraph("• Identify and protect ulnar nerve", styles["bullet"]),
                Paragraph("• Release triceps off medial intermuscular septum", styles["bullet"]),
                Paragraph("• Release triceps off lateral intermuscular septum", styles["bullet"]),
                Paragraph("• Retract triceps medially OR laterally as needed", styles["bullet"]),
                Spacer(1, 0.2*cm),
                Paragraph("<b>Indications:</b> Access without triceps detachment; useful for paediatric distal humeral fractures, lateral condyle, and selected adult cases.", styles["body"]),
                Spacer(1, 0.2*cm),
                Paragraph("<b>Advantage:</b> Triceps insertion completely intact - no triceps weakness.", styles["body"]),
                Paragraph("<b>Limitation:</b> Limited articular window; radial nerve limits proximal extension.", styles["body"]),
            ]
        ]
    ]

    t = Table(col_data, colWidths=[8*cm, 8*cm])
    t.setStyle(TableStyle([
        ("VALIGN", (0,0), (-1,-1), "TOP"),
        ("TOPPADDING", (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING", (0,0), (-1,-1), 8),
        ("RIGHTPADDING", (0,0), (-1,-1), 8),
        ("BACKGROUND", (0,0), (0,0), LIGHT_PURPLE),
        ("BACKGROUND", (1,0), (1,0), LIGHT_BLUE),
        ("BOX", (0,0), (0,0), 1, PURPLE),
        ("BOX", (1,0), (1,0), 1, MED_BLUE),
    ]))
    story.append(t)
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 6: STRUCTURES AT RISK
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("6. STRUCTURES AT RISK & COMPLICATIONS", styles, bg_color=ACCENT_RED))
    story.append(Spacer(1, 0.3*cm))

    story.append(make_nerve_risk_diagram())
    story.append(Spacer(1, 0.2*cm))

    risk_data = [
        ["Structure at Risk", "Mechanism", "Prevention", "Consequence if Injured"],
        ["Ulnar Nerve\n(MOST COMMON)", "Direct cut during dissection;\nexcessive retraction;\nstretch during TEA dislocation",
         "Identify early; Penrose drain;\nanterior transposition in TEA",
         "Cubital tunnel syndrome;\nclaw hand; sensory loss\nring/little fingers"],
        ["Radial Nerve", "Excessive proximal extension\nof incision along humerus;\nretractor placement",
         "Do not extend >10cm proximal\nto lateral epicondyle;\nprotect with retractor under brachialis",
         "Wrist drop (posterior\ninterosseous nerve palsy)"],
        ["Articular Cartilage", "Saw kerf during osteotomy\ncompleting full thickness cut",
         "Always fracture final 1/4\nwith osteotome only;\nuse thin oscillating saw",
         "Damaged articular surface;\npoor reduction; arthritis"],
        ["Triceps Mechanism", "Over-tension at medial\njunction in Bryan-Morrey;\ntransverse division",
         "Extend elbow 20-30°;\ndo NOT cut triceps transversely;\nmaintain tissue as one unit",
         "Permanent extensor weakness;\nextension lag at elbow"],
        ["MCL\n(Medial Collateral Lig.)", "Released for joint dislocation\nin TEA without repair",
         "Repair at closure if released",
         "Valgus instability;\npoor functional outcome"],
        ["Olecranon Osteotomy\nNon-union", "Inadequate fixation;\npoor reduction;\nbone loss from saw kerf",
         "Pre-drill; accurate reduction;\nchevron cut; rigid fixation",
         "Non-union; painful hardware;\nre-operation"],
    ]

    risk_table = Table(risk_data, colWidths=[3.2*cm, 4.5*cm, 4.5*cm, 4.3*cm])
    risk_table.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), ACCENT_RED),
        ("TEXTCOLOR", (0,0), (-1,0), white),
        ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE", (0,0), (-1,0), 8.5),
        ("ALIGN", (0,0), (-1,-1), "LEFT"),
        ("FONTNAME", (0,1), (-1,-1), "Helvetica"),
        ("FONTSIZE", (0,1), (-1,-1), 8),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [white, HexColor("#FDEDEC")]),
        ("GRID", (0,0), (-1,-1), 0.5, MED_GRAY),
        ("TOPPADDING", (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING", (0,0), (-1,-1), 5),
        ("BACKGROUND", (0,1), (0,1), HexColor("#FDECEA")),
        ("TEXTCOLOR", (0,1), (0,1), ACCENT_RED),
        ("FONTNAME", (0,1), (0,1), "Helvetica-Bold"),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
    ]))
    story.append(risk_table)
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 7: INDICATIONS QUICK REFERENCE
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("7. INDICATIONS QUICK REFERENCE", styles, bg_color=ACCENT_GOLD))
    story.append(Spacer(1, 0.3*cm))

    ind_data = [
        ["Clinical Scenario", "Preferred Posterior Variant", "Rationale"],
        ["Intraarticular distal humerus\nfracture (ORIF)", "Olecranon Osteotomy\n(MacAusland-Müller)",
         "Maximum articular surface exposure;\nchevron provides stability"],
        ["Total elbow arthroplasty (TEA)", "Bryan-Morrey\n(Extensile / Triceps-Sparing)",
         "Preserves triceps mechanism;\nrapid rehabilitation"],
        ["Distal humeral non-union", "Olecranon Osteotomy\nOR Bryan-Morrey",
         "Depends on bone quality\nand planned reconstruction"],
        ["Elbow stiffness / contracture\nrelease", "Paratricipital OR\nTriceps Splitting",
         "Preserves triceps;\nadequate capsular access"],
        ["Olecranon fracture ORIF", "Direct posterior\n(minimal approach)",
         "Fracture itself provides\ndirect access"],
        ["Paediatric supracondylar\n/ lateral condyle fractures", "Paratricipital\n(Triceps Slide)",
         "Preserves growth plate;\ntriceps insertion intact"],
        ["Elbow arthroscopy\n(posterior portals)", "Posterior arthroscopic\nportal (direct)",
         "Minimally invasive;\nsuperficial insertion only"],
        ["TEA with poor bone quality\n(elderly)", "Bryan-Morrey exclusively",
         "Avoids osteotomy that\nmay not heal reliably"],
    ]

    ind_table = Table(ind_data, colWidths=[5.5*cm, 5*cm, 6*cm])
    ind_table.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), HexColor("#7D6608")),
        ("TEXTCOLOR", (0,0), (-1,0), white),
        ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE", (0,0), (-1,0), 9),
        ("FONTNAME", (0,1), (-1,-1), "Helvetica"),
        ("FONTSIZE", (0,1), (-1,-1), 8.5),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [white, HexColor("#FEF9E7")]),
        ("GRID", (0,0), (-1,-1), 0.5, MED_GRAY),
        ("TOPPADDING", (0,0), (-1,-1), 6),
        ("BOTTOMPADDING", (0,0), (-1,-1), 6),
        ("LEFTPADDING", (0,0), (-1,-1), 6),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
    ]))
    story.append(ind_table)
    story.append(Spacer(1, 0.5*cm))

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 8: EXAM SUMMARY
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("8. EXAMINATION KEY POINTS (10-MARK ANSWER SUMMARY)", styles, bg_color=DARK_BLUE))
    story.append(Spacer(1, 0.3*cm))

    exam_points = [
        ("1", "NO INTERNERVOUS PLANE", "The posterior approach has no true internervous plane. Access is gained by directly managing the triceps mechanism (reflect, split, or detach)."),
        ("2", "ULNAR NERVE RULE", "Identify and protect the ulnar nerve in EVERY variant. It runs posterior to the medial epicondyle in the cubital tunnel. Transpose anteriorly in TEA."),
        ("3", "OSTEOTOMY = MAXIMUM EXPOSURE", "Olecranon osteotomy (Wilkinson & Stanley) exposes significantly more articular surface of the distal humerus than any triceps-reflecting approach."),
        ("4", "CHEVRON > TRANSVERSE", "Chevron osteotomy (60°, apex distal) is preferred over transverse - better rotational stability and larger healing surface area."),
        ("5", "BARE ZONE", "The non-articular bare zone (~2 cm from the olecranon tip) is the safest site for osteotomy. Identify with direct visualization or fluoroscopy."),
        ("6", "3/4 SAW + 1/4 OSTEOTOME RULE", "Divide only 3/4 depth with the saw; complete the remaining 1/4 with an osteotome to prevent saw kerf through articular cartilage."),
        ("7", "BRYAN-MORREY KEY PEARL", "Periosteum + fascia must be reflected as ONE continuous unit. The medial junction (triceps insertion + fascia + periosteum) is the weakest point. Extend elbow 20-30° to reduce tension."),
        ("8", "RADIAL NERVE LIMITS EXTENSION", "The radial nerve limits proximal extension of the posterior approach along the humerus. Do not extend beyond ~10 cm proximal to the lateral epicondyle."),
        ("9", "TEA DRESSING POSITION", "After total elbow arthroplasty via Bryan-Morrey, dress with elbow at 60° flexion to prevent direct pressure on the wound from the olecranon tip."),
        ("10", "OSTEOTOMY FIXATION", "Pre-drill fixation BEFORE osteotomy. At closure: reduce anatomically and fix with 6.5 mm lag screw + tension band wire (standard), or plate and screws."),
    ]

    for num, title, detail in exam_points:
        data_row = [[
            Paragraph(f"<b>{num}</b>", styles["body_bold"]),
            [Paragraph(f"<b>{title}</b>", styles["body_bold"]),
             Paragraph(detail, styles["body"])]
        ]]
        bg = LIGHT_BLUE if int(num)%2==0 else white
        t = Table(data_row, colWidths=[0.8*cm, 15.7*cm])
        t.setStyle(TableStyle([
            ("ALIGN", (0,0), (0,0), "CENTER"),
            ("VALIGN", (0,0), (-1,-1), "TOP"),
            ("TOPPADDING", (0,0), (-1,-1), 5),
            ("BOTTOMPADDING", (0,0), (-1,-1), 5),
            ("LEFTPADDING", (0,0), (0,0), 2),
            ("LEFTPADDING", (1,0), (1,0), 6),
            ("ROWBACKGROUNDS", (0,0), (-1,-1), [bg]),
        ]))
        story.append(t)

    story.append(Spacer(1, 0.3*cm))
    story.append(HRFlowable(width="100%", thickness=1.5, color=MED_BLUE))
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph(
        "Source: Campbell's Operative Orthopaedics 15th Ed 2026 (pp. 133-135) | "
        "Miller's Review of Orthopaedics 9th Edition (p. 171) | Compiled by Orris Medical AI",
        styles["caption"]
    ))

    # ══════════════════════════════════════════════════════════════════════════
    # BUILD
    # ══════════════════════════════════════════════════════════════════════════

    def page_template(canvas, doc):
        if doc.page == 1:
            cover_background(canvas, doc)
        else:
            regular_page(canvas, doc)

    doc.build(story, onFirstPage=page_template, onLaterPages=page_template)
    print(f"PDF saved to: {OUTPUT_FILE}")


if __name__ == "__main__":
    print("Downloading images...")
    img_paths = download_images()
    print("Building PDF...")
    build_pdf(img_paths)
    print("Done!")
Running Command

cd /home/daytona/workspace/elbow-surgical-guide && python3 generate_guide.py 2>&…

Editing File

~/elbow-surgical-guide/generate_guide.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/elbow-surgical-guide/generate_guide.py'
Running Command

cd /home/daytona/workspace/elbow-surgical-guide && python3 generate_guide.py 2>&…

Editing File

~/elbow-surgical-guide/generate_guide.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/elbow-surgical-guide/generate_guide.py'
Searching Content

"safe_image(" in ~/elbow-surgical-guide

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