Create BDC sallubays of anatomy upper limb joint and lower limb joint Nots

Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
I now have enough textbook content from Gray's Anatomy for Students. Let me compile comprehensive BDC (Broadly Detailed Concise) notes on both upper and lower limb joints.

BDC Study Notes: Anatomy of Upper Limb & Lower Limb Joints

Source: Gray's Anatomy for Students

UPPER LIMB JOINTS


1. SHOULDER (GLENOHUMERAL) JOINT

FeatureDetails
TypeSynovial, multiaxial ball-and-socket joint
BonesHead of humerus + glenoid cavity of scapula
CapsuleLoose; attached to glenoid labrum & anatomical neck of humerus
Articular surfaces:
  • Head of humerus (spherical) - covered by hyaline cartilage
  • Glenoid cavity - deepened by fibrocartilaginous glenoid labrum
Ligaments:
  • Glenohumeral ligaments (superior, middle, inferior) - thickenings of the joint capsule anteriorly
  • Coracohumeral ligament - from coracoid process to greater tubercle; strengthens superior capsule
  • Transverse humeral ligament - bridges the bicipital groove
Movements:
  • Flexion, extension, abduction, adduction, medial/lateral rotation, circumduction (most mobile joint in the body)
Stability:
  • Primarily dependent on rotator cuff muscles (SITS): Supraspinatus, Infraspinatus, Teres minor, Subscapularis
  • Supraspinatus prevents downward dislocation
  • Glenoid labrum deepens socket
Blood supply: Anterior and posterior circumflex humeral arteries
Nerve supply: Axillary nerve, suprascapular nerve, lateral pectoral nerve
Clinical Points:
  • Most common dislocation: anteroinferior (arm in abduction + external rotation)
  • Bankart lesion - avulsion of anteroinferior glenoid labrum (recurrent dislocations)
  • Hill-Sachs lesion - impaction fracture on posterosuperior humeral head

2. ELBOW JOINT

FeatureDetails
TypeCompound synovial joint (3 articulations, 1 joint cavity)
BonesHumerus + Radius + Ulna
Three articulations:
  1. Humero-ulnar joint - trochlea of humerus + trochlear notch of ulna → hinge (flexion/extension)
  2. Humero-radial joint - capitulum of humerus + head of radius → hinge + pivot
  3. Proximal radio-ulnar joint - head of radius + radial notch of ulna → pivot (pronation/supination)
Articular surfaces: All covered by hyaline cartilage
Joint Capsule:
  • Anteriorly: attaches above coronoid & radial fossae; below to coronoid process & annular ligament
  • Posteriorly: attaches above olecranon fossa; below to olecranon
  • Fat pads overlie all three fossae (coronoid, olecranon, radial) - pulled clear by muscle attachments during movement
Ligaments:
  • Medial (ulnar) collateral ligament - 3 bands (anterior, posterior, transverse); supports medial side during valgus stress
  • Lateral (radial) collateral ligament - reinforces lateral capsule
  • Annular ligament of radius - encircles radial head, allows rotation in pronation/supination; blends with radial collateral ligament
Movements: Flexion/extension (humeroulnar & humeroradial); Pronation/supination (proximal radioulnar)
Blood supply: Anastomotic network from brachial, profunda brachii, radial, and ulnar arteries
Nerve supply: Radial nerve (main), musculocutaneous nerve; some contribution from ulnar and median nerves
Clinical Points:
  • Supracondylar fracture (children) - distal fragment displaced posteriorly → may kink brachial artery → Volkmann's ischaemic contracture
  • "Fat pad sign" on X-ray = elevated posterior fat pad = joint effusion (occult fracture)
  • Nursemaid's elbow (pulled elbow) - radial head slips under annular ligament in young children
  • "Carrying angle" ~170° (slight valgus in females > males)
  • Olecranon fracture - avulsion by triceps; direct blow

3. WRIST (RADIOCARPAL) JOINT

FeatureDetails
TypeSynovial, condyloid (ellipsoid) joint
BonesDistal radius + articular disc + proximal carpal row (scaphoid, lunate, triquetrum)
NoteUlna does NOT directly articulate - separated by articular disc (TFCC)
Movements: Flexion, extension (dorsiflexion), abduction (radial deviation), adduction (ulnar deviation), circumduction
Ligaments:
  • Radial collateral ligament - styloid process of radius to scaphoid
  • Ulnar collateral ligament - styloid process of ulna to triquetrum & pisiform
  • Palmar radiocarpal ligament - very strong; prevents hyperextension
  • Dorsal radiocarpal ligament - limits flexion
  • Triangular fibrocartilage complex (TFCC) - articular disc between ulna and carpus
Blood supply: Dorsal and palmar carpal arches
Nerve supply: Anterior and posterior interosseous nerves; branches of radial and ulnar nerves
Clinical Points:
  • Colles' fracture - most common; distal radius fracture with dorsal displacement - "dinner fork deformity" (fall on outstretched hand - FOOSH)
  • Scaphoid fracture - most commonly fractured carpal bone; avascular necrosis risk (blood supply enters distally)
  • TFCC injury - ulnar wrist pain

4. JOINTS OF THE HAND

Carpometacarpal (CMC) joints:
  • Thumb CMC = saddle joint (most mobile) → flexion, extension, abduction, adduction, opposition
  • Fingers 2-5 CMC = plane joints → gliding
Metacarpophalangeal (MCP) joints:
  • Condyloid joints
  • Movements: flexion, extension, abduction, adduction
  • Stabilised by collateral ligaments (taut in flexion) and palmar plates
Interphalangeal (IP) joints:
  • Hinge joints (simple)
  • Only flexion/extension
  • Proximal IP (PIP) and Distal IP (DIP)

LOWER LIMB JOINTS


5. HIP JOINT

FeatureDetails
TypeSynovial, multiaxial ball-and-socket joint
BonesHead of femur + acetabulum of pelvic bone
DesignStability > Mobility (opposite of shoulder)
Articular surfaces:
  • Spherical head of femur - all covered by hyaline cartilage except the fovea
  • Lunate surface of acetabulum - C-shaped, covered by hyaline cartilage; broadest superiorly
  • Rim deepened by fibrocartilaginous acetabular labrum
  • Labrum bridges acetabular notch as the transverse acetabular ligament inferiorly
Ligaments (extra-capsular - very strong):
LigamentOriginInsertionFunction
Iliofemoral (Y-lig. of Bigelow)Anterior inferior iliac spineIntertrochanteric lineResists hyperextension; strongest ligament in body
PubofemoralPubic part of acetabulumAnterior intertrochanteric lineLimits abduction + extension
IschiofemoralPosterior acetabulumGreater trochanterLimits medial rotation
Intra-capsular ligament:
  • Ligament of the head of femur (ligamentum teres) - fovea → acetabular fossa/transverse ligament; carries small branch of obturator artery (blood supply to femoral head)
Movements: Flexion, extension, abduction, adduction, medial/lateral rotation, circumduction
Blood supply to femoral head (clinically vital!):
  1. Medial circumflex femoral artery (main - supplies most of femoral head)
  2. Lateral circumflex femoral artery
  3. Obturator artery via ligamentum teres (minor contribution)
Nerve supply: Femoral, obturator, sciatic, and superior gluteal nerves; follows Hilton's law
Clinical Points:
  • Femoral neck fracture → disrupts medial circumflex femoral artery → avascular necrosis of femoral head
  • Hip dislocation: posterior most common (dashboard injury); limb in flexion, adduction, internal rotation; risk of sciatic nerve injury
  • Perthes disease - avascular necrosis in children (ages 4-8)
  • Developmental dysplasia of the hip (DDH) - shallow acetabulum
  • Trendelenburg sign - gluteus medius weakness (superior gluteal nerve injury)

6. KNEE JOINT

FeatureDetails
TypeLargest synovial joint in the body; modified hinge joint
BonesFemur + Tibia + Patella
Articulations2: tibiofemoral (weight-bearing) + patellofemoral
Articular surfaces:
  • Two femoral condyles (medial > lateral in size)
  • Superior surface of tibial condyles (tibial plateau)
  • Patella (largest sesamoid bone) - articulates with anterior femoral surface; redirects quadriceps pull
Menisci (fibrocartilaginous C-shaped structures):
FeatureMedial MeniscusLateral Meniscus
ShapeC-shaped (larger)O-shaped (smaller, more circular)
AttachmentFirmly attached to tibial collateral ligament + joint capsuleNOT attached to fibular collateral ligament; more mobile
Injury riskMore commonly torn (less mobile)Less commonly torn
Function of menisci: Deepen articular surfaces, distribute load, absorb shock, facilitate lubrication
Ligaments:
LigamentLocationFunction
Tibial (medial) collateral ligamentMedial femoral epicondyle → tibiaResists valgus stress
Fibular (lateral) collateral ligamentLateral femoral epicondyle → head of fibulaResists varus stress
Anterior cruciate ligament (ACL)Anterior tibial intercondylar area → posterior lateral femoral condylePrevents anterior tibial displacement; taut in extension
Posterior cruciate ligament (PCL)Posterior tibial intercondylar area → anterior medial femoral condylePrevents posterior tibial displacement; taut in flexion; stronger than ACL
Bursae around the knee (important!):
  • Prepatellar bursa (housemaid's knee)
  • Infrapatellar bursa (clergyman's knee)
  • Semimembranosus bursa → may communicate with joint (Baker's cyst)
"Locking" mechanism of the knee:
  • In full extension, tibia laterally rotates on femur → screw-home mechanism → joint becomes locked
  • Popliteus muscle unlocks the knee by medially rotating the tibia
Blood supply: Genicular branches of femoral, popliteal, and anterior tibial arteries
Nerve supply: Femoral, obturator, sciatic nerves
Clinical Points:
  • Unhappy triad (O'Donoghue): Valgus force injury → rupture of ACL + medial meniscus + tibial collateral ligament
  • Anterior drawer test - forward pull on tibia with knee at 90° → ACL tear
  • Posterior drawer test - PCL tear
  • McMurray's test - meniscal tear
  • Valgus stress test - medial collateral ligament integrity
  • Lachman's test - most sensitive for ACL injury
  • Unhappy triad is common in contact sports (football, rugby)

7. ANKLE (TALOCRURAL) JOINT

FeatureDetails
TypeSynovial hinge joint
BonesDistal tibia + distal fibula (mortise) + talus
MortiseFormed by medial malleolus (tibia) + lateral malleolus (fibula) + inferior tibial surface
Movements: Plantarflexion, dorsiflexion (mainly)
  • Most stable in dorsiflexion (wider anterior talus fills mortise tightly)
  • Most vulnerable to sprains in plantarflexion (narrower posterior talus = unstable)
Ligaments:
LigamentSideParts
Deltoid ligament (medial)Medial4 parts: tibionavicular, anterior/posterior tibiotalar, tibiocalcaneal; very strong
Lateral ligamentLateral3 parts: Anterior talofibular (ATFL - most commonly injured in ankle sprains), Calcaneofibular (CFL), Posterior talofibular (PTFL)
Clinical Points:
  • Lateral ankle sprain most common - ATFL torn first (plantarflexion + inversion)
  • Pott's fracture - bimalleolar or trimalleolar fracture
  • Deltoid ligament rarely torn (medial ankle sprains uncommon - often bony avulsion instead)

8. SUBTALAR & FOOT JOINTS

Subtalar (talocalcaneal) joint:
  • Type: Plane/synovial
  • Movements: Inversion and eversion of foot (most)
Transverse tarsal (midtarsal) joint:
  • Calcaneocuboid + talonavicular joints together
  • Inversion/eversion contribution
Tarsometatarsal (TMT) joints / Lisfranc joint complex:
  • Plane joints; minimal movement
  • Lisfranc injury - disruption of 2nd TMT joint; can be missed on plain X-rays
Metatarsophalangeal (MTP) joints:
  • Condyloid joints; flexion/extension + abduction/adduction
  • First MTP = hallux valgus site (bunion)

QUICK COMPARISON TABLE

JointTypeKey MovementsMost Common Clinical Problem
ShoulderBall & socketAll (most mobile)Anterior dislocation
ElbowCompound hinge/pivotFlex/ext + pro/supSupracondylar fracture (children)
Wrist (radiocarpal)CondyloidFlex/ext + deviationColles' fracture
HipBall & socketAll (most stable)Neck of femur fracture → AVN
KneeModified hingeFlex/ext + rotationACL tear, meniscal tear
AnkleHingePlantarflex/dorsiflexLateral ligament sprain (ATFL)

NERVE SUPPLY SUMMARY (Upper Limb Joints)

JointNerves
ShoulderAxillary, suprascapular, lateral pectoral
ElbowRadial (main), musculocutaneous, median, ulnar
WristAnterior & posterior interosseous, radial, ulnar

NERVE SUPPLY SUMMARY (Lower Limb Joints)

JointNerves
HipFemoral, obturator, sciatic, superior gluteal
KneeFemoral, obturator, sciatic (common peroneal + tibial)
AnkleDeep peroneal, tibial

All notes compiled from Gray's Anatomy for Students. These are BDC (Broadly Detailed Concise) revision notes covering joint type, bones, articular surfaces, capsule, ligaments, movements, blood supply, nerve supply, and key clinical correlations.

Create a detailed PDF summary of these joint notes with diagrams

Reading File
Reading File
Running Command

mkdir -p /tmp/workspace/joint-notes-pdf && ls /tmp/workspace/

Writing File

~/joint-notes-pdf/generate_pdf.py

"""
BDC Anatomy Notes: Upper Limb & Lower Limb Joints
Detailed PDF with diagrams using ReportLab
"""

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

# ─── Colour Palette ────────────────────────────────────────────────────────────
DARK_BLUE   = colors.HexColor("#1a3a6b")
MED_BLUE    = colors.HexColor("#2563a8")
LIGHT_BLUE  = colors.HexColor("#dce8f7")
ACCENT      = colors.HexColor("#e05c1a")
GOLD        = colors.HexColor("#c89a2a")
LIGHT_GOLD  = colors.HexColor("#fff8e1")
GREEN       = colors.HexColor("#1a7a4a")
LIGHT_GREEN = colors.HexColor("#e6f4ec")
RED         = colors.HexColor("#c0392b")
LIGHT_RED   = colors.HexColor("#fdecea")
PURPLE      = colors.HexColor("#5b2d8e")
LIGHT_PURPLE= colors.HexColor("#ede0f7")
GRAY_LIGHT  = colors.HexColor("#f4f6f8")
GRAY_MED    = colors.HexColor("#b0bec5")
DARK        = colors.HexColor("#222222")
WHITE       = colors.white

PAGE_W, PAGE_H = A4
MARGIN = 18 * mm

# ─── Styles ────────────────────────────────────────────────────────────────────
def make_styles():
    base = getSampleStyleSheet()
    s = {}

    s['cover_title'] = ParagraphStyle('cover_title',
        fontName='Helvetica-Bold', fontSize=28, textColor=WHITE,
        alignment=TA_CENTER, leading=34, spaceAfter=8)

    s['cover_sub'] = ParagraphStyle('cover_sub',
        fontName='Helvetica', fontSize=13, textColor=colors.HexColor("#cde3f7"),
        alignment=TA_CENTER, leading=18, spaceAfter=4)

    s['cover_badge'] = ParagraphStyle('cover_badge',
        fontName='Helvetica-Bold', fontSize=11, textColor=GOLD,
        alignment=TA_CENTER, leading=16)

    s['part_heading'] = ParagraphStyle('part_heading',
        fontName='Helvetica-Bold', fontSize=18, textColor=WHITE,
        alignment=TA_CENTER, leading=22, spaceBefore=6, spaceAfter=6)

    s['joint_title'] = ParagraphStyle('joint_title',
        fontName='Helvetica-Bold', fontSize=14, textColor=WHITE,
        leading=18, spaceBefore=4, spaceAfter=2)

    s['section_head'] = ParagraphStyle('section_head',
        fontName='Helvetica-Bold', fontSize=11, textColor=DARK_BLUE,
        leading=14, spaceBefore=8, spaceAfter=3,
        borderPad=3)

    s['body'] = ParagraphStyle('body',
        fontName='Helvetica', fontSize=9, textColor=DARK,
        leading=13, spaceBefore=1, spaceAfter=1)

    s['bullet'] = ParagraphStyle('bullet',
        fontName='Helvetica', fontSize=9, textColor=DARK,
        leading=12, leftIndent=14, bulletIndent=4,
        spaceBefore=1, spaceAfter=1)

    s['clinical'] = ParagraphStyle('clinical',
        fontName='Helvetica', fontSize=9, textColor=RED,
        leading=12, leftIndent=14, bulletIndent=4,
        spaceBefore=1, spaceAfter=1)

    s['caption'] = ParagraphStyle('caption',
        fontName='Helvetica-Oblique', fontSize=8, textColor=GRAY_MED,
        alignment=TA_CENTER, leading=11, spaceAfter=4)

    s['tbl_hdr'] = ParagraphStyle('tbl_hdr',
        fontName='Helvetica-Bold', fontSize=8.5, textColor=WHITE,
        alignment=TA_CENTER, leading=11)

    s['tbl_cell'] = ParagraphStyle('tbl_cell',
        fontName='Helvetica', fontSize=8.5, textColor=DARK,
        leading=11)

    s['tbl_cell_bold'] = ParagraphStyle('tbl_cell_bold',
        fontName='Helvetica-Bold', fontSize=8.5, textColor=DARK_BLUE,
        leading=11)

    s['footer'] = ParagraphStyle('footer',
        fontName='Helvetica', fontSize=7.5, textColor=GRAY_MED,
        alignment=TA_CENTER)

    return s

S = make_styles()

# ─── Utility Flowables ─────────────────────────────────────────────────────────

class ColorBox(Flowable):
    """A filled rounded rectangle used as a section header background."""
    def __init__(self, w, h, fill_color, radius=6):
        Flowable.__init__(self)
        self.width = w; self.height = h
        self.fill_color = fill_color; self.radius = radius
    def draw(self):
        self.canv.setFillColor(self.fill_color)
        self.canv.roundRect(0, 0, self.width, self.height,
                            self.radius, fill=1, stroke=0)

class JointHeaderBlock(Flowable):
    """Coloured header banner for each joint."""
    def __init__(self, number, title, joint_type, color, width):
        Flowable.__init__(self)
        self.number = number; self.title = title
        self.joint_type = joint_type; self.color = color
        self.width = width; self.height = 38
    def draw(self):
        c = self.canv
        c.setFillColor(self.color)
        c.roundRect(0, 0, self.width, self.height, 8, fill=1, stroke=0)
        # Number circle
        c.setFillColor(WHITE)
        c.circle(20, self.height/2, 13, fill=1, stroke=0)
        c.setFillColor(self.color)
        c.setFont('Helvetica-Bold', 12)
        c.drawCentredString(20, self.height/2 - 4, self.number)
        # Title
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 13)
        c.drawString(42, self.height/2 + 3, self.title)
        # Type badge
        c.setFont('Helvetica', 8)
        c.setFillColor(colors.HexColor("#ffffffaa"))
        badge_text = f"  {self.joint_type}  "
        c.drawString(42, self.height/2 - 11, badge_text)

class DiagramFlowable(Flowable):
    """Base class - all joint diagrams inherit from this."""
    def __init__(self, width, height):
        Flowable.__init__(self)
        self.width = width
        self.height = height

    def _label(self, c, x, y, text, fontsize=7, color=DARK, bold=False):
        c.setFillColor(color)
        c.setFont('Helvetica-Bold' if bold else 'Helvetica', fontsize)
        c.drawCentredString(x, y, text)

    def _label_left(self, c, x, y, text, fontsize=7, color=DARK):
        c.setFillColor(color)
        c.setFont('Helvetica', fontsize)
        c.drawRightString(x, y, text)

    def _label_right(self, c, x, y, text, fontsize=7, color=DARK):
        c.setFillColor(color)
        c.setFont('Helvetica', fontsize)
        c.drawString(x, y, text)

    def _arrow_line(self, c, x1, y1, x2, y2, color=GRAY_MED, width=0.7):
        c.setStrokeColor(color)
        c.setLineWidth(width)
        c.line(x1, y1, x2, y2)

class ShoulderDiagram(DiagramFlowable):
    def draw(self):
        c = self.canv
        cx, cy = self.width/2, self.height/2 + 5

        # Background
        c.setFillColor(LIGHT_BLUE)
        c.roundRect(0, 0, self.width, self.height, 8, fill=1, stroke=0)

        # Scapula glenoid (socket)
        c.setFillColor(colors.HexColor("#b0bec5"))
        c.setStrokeColor(DARK_BLUE)
        c.setLineWidth(1.5)
        c.ellipse(cx-52, cy-18, cx-28, cy+18, fill=1, stroke=1)

        # Glenoid labrum (ring)
        c.setFillColor(colors.HexColor("#e0c070"))
        c.setStrokeColor(GOLD)
        c.setLineWidth(1.2)
        c.ellipse(cx-56, cy-22, cx-24, cy+22, fill=0, stroke=1)

        # Humerus head (ball)
        c.setFillColor(colors.HexColor("#d0d8e8"))
        c.setStrokeColor(DARK_BLUE)
        c.setLineWidth(1.5)
        c.circle(cx+5, cy, 26, fill=1, stroke=1)

        # Humerus shaft
        c.setFillColor(colors.HexColor("#d0d8e8"))
        c.setStrokeColor(DARK_BLUE)
        c.setLineWidth(1.5)
        c.rect(cx+14, cy-42, 18, 42, fill=1, stroke=1)

        # Joint capsule outline
        c.setStrokeColor(MED_BLUE)
        c.setLineWidth(1.2)
        c.setDash([3,2])
        c.ellipse(cx-30, cy-30, cx+38, cy+30, fill=0, stroke=1)
        c.setDash([])

        # Acromion / coracoid process (simplified)
        c.setFillColor(colors.HexColor("#90a4ae"))
        c.setStrokeColor(DARK_BLUE)
        c.setLineWidth(1)
        # Acromion - flat bone above
        pts = [cx-40, cy+38, cx+10, cy+38, cx+18, cy+28, cx-32, cy+28]
        c.polygon(pts, fill=1, stroke=1)

        # Coracohumeral ligament line
        c.setStrokeColor(GREEN)
        c.setLineWidth(1.4)
        c.line(cx-20, cy+28, cx+5, cy+20)

        # Rotator cuff arc
        c.setStrokeColor(ACCENT)
        c.setLineWidth(2)
        c.arc(cx-18, cy-30, cx+36, cy+36, 30, 120)

        # Labels
        self._label(c, cx-40, cy+42, "Acromion", 7, DARK_BLUE, True)
        self._label(c, cx-40, cy-26, "Glenoid\nLabrum", 6.5, GOLD)
        self._label(c, cx+5, cy+6, "Humeral\nHead", 6.5, DARK_BLUE)
        self._label(c, cx+5, cy-48, "Humerus\nShaft", 6.5, DARK_BLUE)
        self._label(c, cx-40, cy+3, "Glenoid\nFossa", 6.5, colors.HexColor("#546e7a"))
        self._label(c, cx+28, cy+24, "Rotator\nCuff", 6.5, ACCENT)
        self._label(c, cx-5, cy+22, "Coracohumeral\nLig.", 6, GREEN)

        # Title
        self._label(c, self.width/2, 8, "Shoulder (Glenohumeral) Joint - Schematic", 7.5, DARK_BLUE, True)


class ElbowDiagram(DiagramFlowable):
    def draw(self):
        c = self.canv
        cx, cy = self.width/2, self.height/2 + 8

        # Background
        c.setFillColor(LIGHT_GREEN)
        c.roundRect(0, 0, self.width, self.height, 8, fill=1, stroke=0)

        bone_color = colors.HexColor("#d0d8e8")
        bone_stroke = DARK_BLUE

        # Humerus (upper bone)
        c.setFillColor(bone_color); c.setStrokeColor(bone_stroke); c.setLineWidth(1.5)
        c.rect(cx-18, cy+10, 36, 48, fill=1, stroke=1)
        # Medial epicondyle
        c.ellipse(cx-28, cy+8, cx-14, cy+22, fill=1, stroke=1)
        # Lateral epicondyle
        c.ellipse(cx+14, cy+8, cx+28, cy+22, fill=1, stroke=1)
        # Trochlea
        c.setFillColor(colors.HexColor("#a8c0d6"))
        c.ellipse(cx-15, cy+5, cx+3, cy+18, fill=1, stroke=1)
        # Capitulum
        c.setFillColor(colors.HexColor("#a8c0d6"))
        c.ellipse(cx+3, cy+5, cx+18, cy+18, fill=1, stroke=1)

        # Ulna
        c.setFillColor(bone_color); c.setStrokeColor(bone_stroke); c.setLineWidth(1.5)
        c.rect(cx-20, cy-55, 20, 58, fill=1, stroke=1)
        # Olecranon
        c.ellipse(cx-22, cy, cx-2, cy+16, fill=1, stroke=1)
        # Coronoid process
        c.polygon([cx-20, cy+4, cx-8, cy+4, cx-8, cy-2, cx-20, cy-2], fill=1, stroke=1)

        # Radius
        c.setFillColor(bone_color); c.setStrokeColor(bone_stroke); c.setLineWidth(1.5)
        # Radial head circle
        c.circle(cx+10, cy+2, 10, fill=1, stroke=1)
        c.rect(cx+3, cy-55, 14, 55, fill=1, stroke=1)

        # Annular ligament
        c.setFillColor(colors.HexColor("#e0c07080"))
        c.setStrokeColor(GOLD)
        c.setLineWidth(2)
        c.ellipse(cx+1, cy-7, cx+19, cy+11, fill=0, stroke=1)

        # MCL line
        c.setStrokeColor(RED); c.setLineWidth(2)
        c.line(cx-24, cy+14, cx-14, cy-4)
        # LCL line
        c.setStrokeColor(MED_BLUE); c.setLineWidth(2)
        c.line(cx+22, cy+14, cx+18, cy-4)

        # Labels
        self._label(c, cx, cy+58, "Humerus", 7, DARK_BLUE, True)
        self._label(c, cx-22, cy+24, "Medial\nEpicondyle", 6, DARK_BLUE)
        self._label(c, cx+22, cy+24, "Lateral\nEpicondyle", 6, DARK_BLUE)
        self._label(c, cx-10, cy+10, "Trochlea", 6, colors.HexColor("#546e7a"))
        self._label(c, cx+10, cy+10, "Capitulum", 6, colors.HexColor("#546e7a"))
        self._label(c, cx-28, cy-10, "Olecranon", 6.5, DARK_BLUE)
        self._label_right(c, cx+42, cy+2, "Radial Head", 6.5, DARK_BLUE)
        self._label_right(c, cx+42, cy-10, "Annular Lig.", 6.5, GOLD)
        self._label_left(c, cx-32, cy-10, "MCL", 6.5, RED)
        self._label_right(c, cx+38, cy-18, "LCL", 6.5, MED_BLUE)

        self._label(c, self.width/2, 8, "Elbow Joint - Schematic (Anterior View)", 7.5, DARK_BLUE, True)


class HipDiagram(DiagramFlowable):
    def draw(self):
        c = self.canv
        cx, cy = self.width/2, self.height/2 + 8

        # Background
        c.setFillColor(LIGHT_PURPLE)
        c.roundRect(0, 0, self.width, self.height, 8, fill=1, stroke=0)

        bone_color = colors.HexColor("#d0d8e8")
        bone_stroke = DARK_BLUE

        # Acetabulum cup
        c.setFillColor(colors.HexColor("#b0bec5"))
        c.setStrokeColor(bone_stroke); c.setLineWidth(1.5)
        c.circle(cx-10, cy, 36, fill=1, stroke=1)

        # Acetabular labrum
        c.setFillColor(colors.HexColor("#e0c07080"))
        c.setStrokeColor(GOLD); c.setLineWidth(2)
        c.circle(cx-10, cy, 40, fill=0, stroke=1)

        # Femoral head (ball)
        c.setFillColor(bone_color); c.setStrokeColor(bone_stroke); c.setLineWidth(1.8)
        c.circle(cx-10, cy, 30, fill=1, stroke=1)

        # Fovea
        c.setFillColor(colors.HexColor("#90a4ae"))
        c.circle(cx-18, cy+5, 4, fill=1, stroke=0)

        # Femoral neck
        c.setFillColor(bone_color); c.setStrokeColor(bone_stroke); c.setLineWidth(1.5)
        c.polygon([cx+18, cy+10, cx+24, cy-8, cx+56, cy-32, cx+62, cy-10,
                   cx+30, cy+20], fill=1, stroke=1)

        # Femoral shaft
        c.rect(cx+48, cy-32, 22, -60, fill=1, stroke=1)

        # Greater trochanter
        c.ellipse(cx+52, cy-28, cx+74, cy-8, fill=1, stroke=1)

        # Ligaments
        # Iliofemoral (Y-ligament)
        c.setStrokeColor(ACCENT); c.setLineWidth(2.5)
        c.line(cx-10, cy-32, cx+18, cy+10)
        c.line(cx-10, cy-38, cx+20, cy-2)
        # Ligamentum teres
        c.setStrokeColor(GREEN); c.setLineWidth(1.8)
        c.setDash([3,2])
        c.line(cx-18, cy+5, cx-10, cy+20)
        c.setDash([])

        # Labels
        self._label(c, cx-10, cy+2, "Femoral\nHead", 7, DARK_BLUE, True)
        self._label(c, cx-10, cy-46, "Acetabulum", 7, DARK_BLUE, True)
        self._label(c, cx-42, cy, "Acetabular\nLabrum", 6.5, GOLD)
        self._label(c, cx-20, cy+10, "Fovea", 6, colors.HexColor("#546e7a"))
        self._label(c, cx+68, cy-38, "Greater\nTrochanter", 6.5, DARK_BLUE)
        self._label_right(c, cx-46, cy+10, "Iliofemoral\nLig. (Y-lig.)", 6.5, ACCENT)
        self._label_right(c, cx-46, cy-8, "Lig. of\nFemoral Head", 6.5, GREEN)

        self._label(c, self.width/2, 8, "Hip Joint - Schematic (Anterior View)", 7.5, DARK_BLUE, True)


class KneeDiagram(DiagramFlowable):
    def draw(self):
        c = self.canv
        cx, cy = self.width/2, self.height/2 + 5

        c.setFillColor(LIGHT_GOLD)
        c.roundRect(0, 0, self.width, self.height, 8, fill=1, stroke=0)

        bone_color = colors.HexColor("#d0d8e8")
        bone_stroke = DARK_BLUE
        cart_color = colors.HexColor("#a8d8b0")

        # Femur condyles
        c.setFillColor(bone_color); c.setStrokeColor(bone_stroke); c.setLineWidth(1.5)
        c.rect(cx-22, cy+10, 44, 55, fill=1, stroke=1)
        # Medial condyle
        c.ellipse(cx-30, cy, cx-4, cy+22, fill=1, stroke=1)
        # Lateral condyle
        c.ellipse(cx+4, cy, cx+30, cy+22, fill=1, stroke=1)

        # Tibia plateau
        c.setFillColor(bone_color); c.setStrokeColor(bone_stroke); c.setLineWidth(1.5)
        c.rect(cx-28, cy-12, 56, 14, fill=1, stroke=1)
        c.rect(cx-22, cy-55, 44, 44, fill=1, stroke=1)

        # Cartilage on tibia
        c.setFillColor(cart_color); c.setStrokeColor(GREEN); c.setLineWidth(0.8)
        c.ellipse(cx-30, cy-8, cx-2, cy+4, fill=1, stroke=1)
        c.ellipse(cx+2, cy-8, cx+30, cy+4, fill=1, stroke=1)

        # Medial meniscus (C-shape)
        c.setFillColor(colors.HexColor("#e0c070")); c.setStrokeColor(GOLD); c.setLineWidth(1.2)
        c.arc(cx-28, cy-6, cx-6, cy+6, 30, 300)

        # Lateral meniscus (more circular)
        c.arc(cx+6, cy-6, cx+26, cy+6, 30, 330)

        # Patella
        c.setFillColor(bone_color); c.setStrokeColor(bone_stroke); c.setLineWidth(1.5)
        c.ellipse(cx-12, cy+26, cx+12, cy+50, fill=1, stroke=1)
        self._label(c, cx, cy+38, "Patella", 6.5, DARK_BLUE, True)

        # ACL
        c.setStrokeColor(ACCENT); c.setLineWidth(2)
        c.line(cx-4, cy-2, cx+12, cy+14)

        # PCL
        c.setStrokeColor(MED_BLUE); c.setLineWidth(2)
        c.line(cx+4, cy-2, cx-12, cy+14)

        # MCL
        c.setStrokeColor(RED); c.setLineWidth(2)
        c.line(cx-30, cy+14, cx-30, cy-8)

        # LCL
        c.setStrokeColor(GREEN); c.setLineWidth(2)
        c.line(cx+30, cy+14, cx+30, cy-8)

        # Labels
        self._label(c, cx, cy+66, "Femur", 7, DARK_BLUE, True)
        self._label(c, cx, cy-48, "Tibia", 7, DARK_BLUE, True)
        self._label(c, cx-18, cy+8, "Medial\nCondyle", 6, DARK_BLUE)
        self._label(c, cx+18, cy+8, "Lateral\nCondyle", 6, DARK_BLUE)
        self._label_left(c, cx-38, cy+8, "MCL", 6.5, RED)
        self._label_right(c, cx+38, cy+8, "LCL", 6.5, GREEN)
        self._label(c, cx-4, cy+6, "ACL", 6, ACCENT)
        self._label(c, cx+6, cy+6, "PCL", 6, MED_BLUE)
        self._label(c, cx-14, cy-4, "Med.\nMeniscus", 5.5, GOLD)
        self._label(c, cx+14, cy-4, "Lat.\nMeniscus", 5.5, GOLD)

        self._label(c, self.width/2, 8, "Knee Joint - Schematic (Anterior View)", 7.5, DARK_BLUE, True)


class AnkleDiagram(DiagramFlowable):
    def draw(self):
        c = self.canv
        cx, cy = self.width/2, self.height/2 + 5

        c.setFillColor(LIGHT_RED)
        c.roundRect(0, 0, self.width, self.height, 8, fill=1, stroke=0)

        bone_color = colors.HexColor("#d0d8e8")
        bone_stroke = DARK_BLUE

        # Tibia
        c.setFillColor(bone_color); c.setStrokeColor(bone_stroke); c.setLineWidth(1.5)
        c.rect(cx-20, cy+10, 38, 55, fill=1, stroke=1)
        # Medial malleolus
        c.ellipse(cx-28, cy-5, cx-12, cy+16, fill=1, stroke=1)

        # Fibula
        c.setFillColor(bone_color); c.setStrokeColor(bone_stroke); c.setLineWidth(1.5)
        c.rect(cx+22, cy+10, 14, 55, fill=1, stroke=1)
        # Lateral malleolus
        c.ellipse(cx+14, cy-10, cx+36, cy+12, fill=1, stroke=1)

        # Talus
        c.setFillColor(colors.HexColor("#b0bec5")); c.setStrokeColor(bone_stroke); c.setLineWidth(1.5)
        c.rect(cx-22, cy-25, 54, 22, fill=1, stroke=1)

        # Calcaneus
        c.setFillColor(bone_color); c.setStrokeColor(bone_stroke); c.setLineWidth(1.2)
        c.ellipse(cx-16, cy-52, cx+32, cy-22, fill=1, stroke=1)

        # Deltoid ligament (medial, fan shape)
        c.setStrokeColor(RED); c.setLineWidth(1.8)
        for angle in [-20, 0, 20, 40]:
            rad = math.radians(angle + 270)
            c.line(cx-20, cy+2,
                   cx-20 + 22*math.cos(rad),
                   cy+2 + 22*math.sin(rad))

        # ATFL
        c.setStrokeColor(ACCENT); c.setLineWidth(2)
        c.line(cx+25, cy+2, cx+8, cy-10)

        # CFL
        c.setStrokeColor(PURPLE); c.setLineWidth(2)
        c.line(cx+25, cy, cx+14, cy-36)

        # Labels
        self._label(c, cx, cy+60, "Tibia", 7, DARK_BLUE, True)
        self._label(c, cx+29, cy+58, "Fibula", 7, DARK_BLUE, True)
        self._label(c, cx, cy-14, "Talus", 7, DARK_BLUE, True)
        self._label(c, cx+8, cy-40, "Calcaneus", 7, DARK_BLUE, True)
        self._label(c, cx-28, cy+12, "Med.\nMalleolus", 6, DARK_BLUE)
        self._label(c, cx+28, cy+16, "Lat.\nMalleolus", 6, DARK_BLUE)
        self._label_left(c, cx-36, cy-6, "Deltoid\nLig.", 6.5, RED)
        self._label_right(c, cx+46, cy-4, "ATFL", 6.5, ACCENT)
        self._label_right(c, cx+46, cy-22, "CFL", 6.5, PURPLE)

        self._label(c, self.width/2, 8, "Ankle (Talocrural) Joint - Schematic", 7.5, DARK_BLUE, True)


# ─── Helper functions ──────────────────────────────────────────────────────────

def section_header(text, color=MED_BLUE):
    return Paragraph(f'<font color="white"><b> {text} </b></font>',
                     ParagraphStyle('sh', fontName='Helvetica-Bold',
                                    fontSize=10, textColor=WHITE,
                                    backColor=color, leading=16,
                                    spaceBefore=10, spaceAfter=4,
                                    borderPad=5, leftIndent=0))

def sub_header(text):
    return Paragraph(f'<b><font color="#1a3a6b">{text}</font></b>', S['section_head'])

def body(text):
    return Paragraph(text, S['body'])

def bullet(text, color=DARK):
    return Paragraph(f"• {text}", S['bullet'])

def clinical_note(text):
    return Paragraph(f"⚠ {text}", S['clinical'])

def space(h=4):
    return Spacer(1, h)

def hr(color=GRAY_MED):
    return HRFlowable(width="100%", thickness=0.5, color=color, spaceAfter=4, spaceBefore=4)

def make_table(data, col_widths=None, hdr_color=DARK_BLUE, alt_color=LIGHT_BLUE):
    """Creates a styled table. data[0] = headers."""
    table_data = []
    # Header row
    hdr = [Paragraph(str(c), S['tbl_hdr']) for c in data[0]]
    table_data.append(hdr)
    for i, row in enumerate(data[1:]):
        cells = []
        for j, cell in enumerate(row):
            style = S['tbl_cell_bold'] if j == 0 else S['tbl_cell']
            cells.append(Paragraph(str(cell), style))
        table_data.append(cells)

    avail = PAGE_W - 2*MARGIN
    if col_widths is None:
        n = len(data[0])
        col_widths = [avail/n] * n

    t = Table(table_data, colWidths=col_widths, repeatRows=1)
    style_cmds = [
        ('BACKGROUND', (0,0), (-1,0), hdr_color),
        ('TEXTCOLOR',  (0,0), (-1,0), WHITE),
        ('FONTNAME',   (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE',   (0,0), (-1,-1), 8.5),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, alt_color]),
        ('GRID',       (0,0), (-1,-1), 0.4, GRAY_MED),
        ('VALIGN',     (0,0), (-1,-1), 'TOP'),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING',   (0,0), (-1,-1), 5),
        ('RIGHTPADDING',  (0,0), (-1,-1), 5),
        ('LINEBELOW',  (0,0), (-1,0), 1.5, hdr_color),
    ]
    t.setStyle(TableStyle(style_cmds))
    return t

def joint_header(num, title, jtype, color):
    return JointHeaderBlock(str(num), title, jtype, color, PAGE_W - 2*MARGIN)

# ─── Cover Page ────────────────────────────────────────────────────────────────

def cover_page():
    elems = []

    class CoverBg(Flowable):
        def __init__(self, w, h):
            Flowable.__init__(self); self.width=w; self.height=h
        def draw(self):
            c = self.canv
            # Gradient-like background using two rects
            c.setFillColor(DARK_BLUE); c.rect(0, 0, self.width, self.height, fill=1, stroke=0)
            c.setFillColor(colors.HexColor("#0d2550"))
            c.rect(0, 0, self.width, self.height*0.45, fill=1, stroke=0)
            # Decorative circles
            c.setFillColor(colors.HexColor("#ffffff08"))
            c.circle(self.width*0.85, self.height*0.8, 120, fill=1, stroke=0)
            c.circle(self.width*0.1, self.height*0.2, 80, fill=1, stroke=0)
            c.circle(self.width*0.5, self.height*0.5, 200, fill=0, stroke=1)
            c.setStrokeColor(colors.HexColor("#ffffff10")); c.setLineWidth(0.5)
            c.circle(self.width*0.5, self.height*0.5, 240, fill=0, stroke=1)
            # Gold accent bar
            c.setFillColor(GOLD)
            c.rect(MARGIN, self.height*0.52, self.width - 2*MARGIN, 3, fill=1, stroke=0)

    elems.append(CoverBg(PAGE_W, PAGE_H))

    # Cover content as a table positioned over background
    cover_content = [
        Spacer(1, PAGE_H * 0.22),
        Paragraph("BDC ANATOMY NOTES", ParagraphStyle('ct',
            fontName='Helvetica-Bold', fontSize=11, textColor=GOLD,
            alignment=TA_CENTER, leading=16, letterSpacing=3)),
        Spacer(1, 10),
        Paragraph("Upper Limb & Lower Limb<br/>Joints", ParagraphStyle('ctitle',
            fontName='Helvetica-Bold', fontSize=32, textColor=WHITE,
            alignment=TA_CENTER, leading=38)),
        Spacer(1, 18),
        Paragraph("Comprehensive Study Notes with Diagrams", ParagraphStyle('csub',
            fontName='Helvetica', fontSize=13, textColor=colors.HexColor("#cde3f7"),
            alignment=TA_CENTER, leading=18)),
        Spacer(1, 30),
        Paragraph("─────────────────────────────────────────────────", ParagraphStyle('div',
            fontName='Helvetica', fontSize=9, textColor=colors.HexColor("#4a7abd"),
            alignment=TA_CENTER)),
        Spacer(1, 18),
        Paragraph(
            "Shoulder • Elbow • Wrist • Hand<br/>Hip • Knee • Ankle • Foot",
            ParagraphStyle('joints', fontName='Helvetica', fontSize=12,
                           textColor=colors.HexColor("#b0d0f0"), alignment=TA_CENTER, leading=20)
        ),
        Spacer(1, 30),
        # Info badges
        Table([[
            Paragraph("8 Joints<br/>Covered", ParagraphStyle('badge', fontName='Helvetica-Bold',
                fontSize=9, textColor=DARK_BLUE, alignment=TA_CENTER, backColor=GOLD,
                borderPad=6, leading=13)),
            Paragraph("Full Clinical<br/>Correlations", ParagraphStyle('badge2', fontName='Helvetica-Bold',
                fontSize=9, textColor=WHITE, alignment=TA_CENTER, backColor=MED_BLUE,
                borderPad=6, leading=13)),
            Paragraph("Ligament<br/>Tables", ParagraphStyle('badge3', fontName='Helvetica-Bold',
                fontSize=9, textColor=WHITE, alignment=TA_CENTER, backColor=GREEN,
                borderPad=6, leading=13)),
            Paragraph("Nerve & Blood<br/>Supply", ParagraphStyle('badge4', fontName='Helvetica-Bold',
                fontSize=9, textColor=WHITE, alignment=TA_CENTER, backColor=ACCENT,
                borderPad=6, leading=13)),
        ]], colWidths=[80, 88, 80, 88], hAlign='CENTER'),
        Spacer(1, 40),
        Paragraph("Source: Gray's Anatomy for Students", ParagraphStyle('src',
            fontName='Helvetica-Oblique', fontSize=9, textColor=colors.HexColor("#7a9abf"),
            alignment=TA_CENTER)),
    ]
    elems.extend(cover_content)
    return elems

# ─── Build document ────────────────────────────────────────────────────────────

def build():
    path = "/tmp/workspace/joint-notes-pdf/BDC_Joint_Notes.pdf"
    doc = SimpleDocTemplate(path, pagesize=A4,
                            leftMargin=MARGIN, rightMargin=MARGIN,
                            topMargin=MARGIN, bottomMargin=MARGIN+5)

    avail_w = PAGE_W - 2*MARGIN
    elems = []

    # ── Cover ──
    elems += cover_page()
    elems.append(PageBreak())

    # ══════════════════════════════════════════════════════
    # PART 1: UPPER LIMB JOINTS
    # ══════════════════════════════════════════════════════
    class PartBanner(Flowable):
        def __init__(self, title, subtitle, color, w):
            Flowable.__init__(self); self.title=title; self.subtitle=subtitle
            self.color=color; self.width=w; self.height=52
        def draw(self):
            c = self.canv
            c.setFillColor(self.color)
            c.roundRect(0, 0, self.width, self.height, 10, fill=1, stroke=0)
            c.setFillColor(colors.HexColor("#ffffff15"))
            c.circle(self.width-30, self.height/2, 40, fill=1, stroke=0)
            c.setFillColor(WHITE)
            c.setFont('Helvetica-Bold', 16)
            c.drawString(14, self.height/2+6, self.title)
            c.setFont('Helvetica', 10)
            c.setFillColor(colors.HexColor("#ffffffcc"))
            c.drawString(14, self.height/2-10, self.subtitle)

    elems.append(PartBanner("PART 1: UPPER LIMB JOINTS",
        "Shoulder  •  Elbow  •  Wrist  •  Hand", DARK_BLUE, avail_w))
    elems.append(space(10))

    # ── 1. SHOULDER JOINT ──────────────────────────────────────────────────────
    elems.append(joint_header(1, "SHOULDER (GLENOHUMERAL) JOINT", "Synovial Ball & Socket", MED_BLUE))
    elems.append(space(6))

    # Two-column layout: diagram left, key facts right
    diag = ShoulderDiagram(avail_w * 0.48, 160)
    facts_data = [
        ["Feature", "Details"],
        ["Type", "Synovial multiaxial ball & socket"],
        ["Bones", "Head of humerus + glenoid cavity"],
        ["Stability", "Primarily muscular (rotator cuff)"],
        ["Mobility", "Most mobile joint in the body"],
        ["Capsule", "Loose; allows wide ROM"],
    ]
    facts_tbl = make_table(facts_data, col_widths=[avail_w*0.48*0.38, avail_w*0.48*0.62])
    combo = Table([[diag, facts_tbl]], colWidths=[avail_w*0.48, avail_w*0.52])
    combo.setStyle(TableStyle([('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),0),
                                ('RIGHTPADDING',(0,0),(-1,-1),4)]))
    elems.append(combo)
    elems.append(space(4))

    elems.append(section_header("ROTATOR CUFF (SITS)", GREEN))
    rotator_data = [
        ["Muscle", "Origin", "Insertion", "Action"],
        ["Supraspinatus", "Supraspinous fossa", "Greater tubercle (sup.)", "Abduction (initiates 0-15°)"],
        ["Infraspinatus", "Infraspinous fossa", "Greater tubercle (mid.)", "Lateral rotation"],
        ["Teres minor", "Lateral border scapula", "Greater tubercle (inf.)", "Lateral rotation"],
        ["Subscapularis", "Subscapular fossa", "Lesser tubercle", "Medial rotation"],
    ]
    elems.append(make_table(rotator_data, col_widths=[avail_w*0.2, avail_w*0.27, avail_w*0.27, avail_w*0.26],
                            hdr_color=GREEN))
    elems.append(space(4))

    elems.append(section_header("LIGAMENTS", MED_BLUE))
    lig_data = [
        ["Ligament", "Attachment", "Function"],
        ["Glenohumeral (sup/mid/inf)", "Glenoid rim → lesser tubercle/neck humerus", "Anterior capsule reinforcement"],
        ["Coracohumeral", "Coracoid process → greater tubercle", "Limits inferior dislocation & ext rotation"],
        ["Transverse humeral", "Bridges bicipital groove", "Retains biceps tendon (long head)"],
        ["Coracoacromial", "Coracoid → acromion (NOT part of joint)", "Arch; prevents superior dislocation"],
    ]
    elems.append(make_table(lig_data, col_widths=[avail_w*0.30, avail_w*0.38, avail_w*0.32]))
    elems.append(space(4))

    elems.append(section_header("MOVEMENTS & NERVE/BLOOD SUPPLY", MED_BLUE))
    elems.append(body("<b>Movements:</b> Flexion, Extension, Abduction, Adduction, Medial rotation, Lateral rotation, Circumduction"))
    elems.append(body("<b>Nerve supply:</b> Axillary nerve (C5,C6) | Suprascapular nerve (C5,C6) | Lateral pectoral nerve"))
    elems.append(body("<b>Blood supply:</b> Anterior & posterior circumflex humeral arteries (from axillary artery)"))
    elems.append(space(4))

    elems.append(section_header("CLINICAL CORRELATIONS", RED))
    elems.append(clinical_note("<b>Anterior dislocation</b> (95%): arm abducted + externally rotated. Risks: axillary nerve injury → deltoid paralysis & loss of sensation regimental badge area"))
    elems.append(clinical_note("<b>Bankart lesion:</b> avulsion of anteroinferior glenoid labrum in recurrent dislocations"))
    elems.append(clinical_note("<b>Hill-Sachs lesion:</b> impaction fracture posterosuperior humeral head (from repeated dislocations)"))
    elems.append(clinical_note("<b>Rotator cuff tear:</b> supraspinatus most commonly torn; tested by painful arc (60-120°) and empty can test"))
    elems.append(clinical_note("<b>Frozen shoulder (adhesive capsulitis):</b> painful progressive stiffness; capsule contracted"))

    elems.append(PageBreak())

    # ── 2. ELBOW JOINT ──────────────────────────────────────────────────────────
    elems.append(joint_header(2, "ELBOW JOINT", "Compound Synovial (Hinge + Pivot)", colors.HexColor("#1a7a4a")))
    elems.append(space(6))

    diag2 = ElbowDiagram(avail_w * 0.46, 170)
    artic_data = [
        ["Articulation", "Bones", "Type", "Movement"],
        ["Humeroulnar", "Trochlea + Trochlear notch of ulna", "Hinge", "Flexion / Extension"],
        ["Humeroradial", "Capitulum + Head of radius", "Hinge + Pivot", "Flexion / Extension"],
        ["Proximal radioulnar", "Head of radius + Radial notch of ulna", "Pivot", "Pronation / Supination"],
    ]
    artic_tbl = make_table(artic_data, col_widths=[avail_w*0.52*0.22, avail_w*0.52*0.38,
                                                    avail_w*0.52*0.18, avail_w*0.52*0.22])
    combo2 = Table([[diag2, artic_tbl]], colWidths=[avail_w*0.46, avail_w*0.54])
    combo2.setStyle(TableStyle([('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),0),
                                 ('RIGHTPADDING',(0,0),(-1,-1),4)]))
    elems.append(combo2)
    elems.append(space(4))

    elems.append(section_header("LIGAMENTS", colors.HexColor("#1a7a4a")))
    elib_data = [
        ["Ligament", "Origin", "Insertion", "Resists"],
        ["Medial (ulnar) collateral", "Medial epicondyle of humerus", "Coronoid process + olecranon (ulna)", "Valgus stress"],
        ["Lateral (radial) collateral", "Lateral epicondyle of humerus", "Annular ligament + ulna", "Varus stress"],
        ["Annular ligament of radius", "Anterior radial notch of ulna", "Posterior radial notch of ulna", "Radial head dislocation"],
    ]
    elems.append(make_table(elib_data, col_widths=[avail_w*0.28, avail_w*0.26, avail_w*0.26, avail_w*0.20],
                            hdr_color=colors.HexColor("#1a7a4a"), alt_color=LIGHT_GREEN))
    elems.append(space(4))

    elems.append(section_header("NERVE & BLOOD SUPPLY", colors.HexColor("#1a7a4a")))
    elems.append(body("<b>Nerve supply:</b> Radial nerve (main) | Musculocutaneous | Median | Ulnar"))
    elems.append(body("<b>Blood supply:</b> Anastomotic network - brachial, profunda brachii, radial, ulnar arteries"))
    elems.append(space(4))

    elems.append(section_header("CLINICAL CORRELATIONS", RED))
    elems.append(clinical_note("<b>Supracondylar fracture</b> (children): distal fragment displaced posteriorly by triceps → brachial artery kinking → Volkmann's ischaemic contracture (anterior compartment)"))
    elems.append(clinical_note("<b>Fat pad sign</b>: elevated posterior fat pad on X-ray = joint effusion = occult fracture (especially radial head in adults)"))
    elems.append(clinical_note("<b>Nursemaid's elbow</b> (pulled elbow, <5 years): radial head subluxation under annular ligament; treated by supination + flexion"))
    elems.append(clinical_note("<b>Olecranon fracture</b>: avulsion by triceps or direct blow; gap in extensor mechanism"))
    elems.append(clinical_note("<b>Carrying angle</b>: ~170° valgus (females > males); increased = cubitus valgus → tardy ulnar nerve palsy"))
    elems.append(clinical_note("<b>Medial epicondyle fracture</b>: commonest fracture around elbow in children; ulnar nerve at risk"))

    elems.append(PageBreak())

    # ── 3. WRIST JOINT ─────────────────────────────────────────────────────────
    elems.append(joint_header(3, "WRIST (RADIOCARPAL) JOINT", "Synovial Condyloid (Ellipsoid)", colors.HexColor("#5b2d8e")))
    elems.append(space(6))

    wrist_overview = [
        ["Feature", "Details"],
        ["Type", "Synovial condyloid (ellipsoid)"],
        ["Proximal surface", "Distal radius + articular disc (TFCC)"],
        ["Distal surface", "Scaphoid + Lunate + Triquetrum (proximal row)"],
        ["Note on ulna", "Does NOT directly articulate; separated by TFCC"],
        ["Movements", "Flex, Ext, Radial deviation, Ulnar deviation, Circumduction"],
    ]
    elems.append(make_table(wrist_overview, col_widths=[avail_w*0.35, avail_w*0.65],
                            hdr_color=PURPLE, alt_color=LIGHT_PURPLE))
    elems.append(space(5))

    elems.append(section_header("LIGAMENTS OF WRIST", PURPLE))
    wrist_lig = [
        ["Ligament", "Sides", "Details"],
        ["Radial collateral lig.", "Lateral (radial)", "Radial styloid → scaphoid & trapezium"],
        ["Ulnar collateral lig.", "Medial (ulnar)", "Ulnar styloid → triquetrum & pisiform"],
        ["Palmar radiocarpal lig.", "Anterior", "Radius → carpals; very strong; prevents hyperextension"],
        ["Dorsal radiocarpal lig.", "Posterior", "Radius → carpals; limits flexion"],
        ["TFCC (triangular fibrocartilage complex)", "Ulnar side", "Articular disc + ligaments; key stabiliser of distal radioulnar + wrist"],
    ]
    elems.append(make_table(wrist_lig, col_widths=[avail_w*0.30, avail_w*0.18, avail_w*0.52],
                            hdr_color=PURPLE, alt_color=LIGHT_PURPLE))
    elems.append(space(5))

    elems.append(section_header("CARPAL BONES (Mnemonic)", PURPLE))
    elems.append(body('<b>Proximal row:</b> Scaphoid — Lunate — Triquetrum — Pisiform'))
    elems.append(body('<b>Distal row:</b> Trapezium — Trapezoid — Capitate — Hamate'))
    elems.append(body('<b>Mnemonic:</b> <i>"Some Lovers Try Positions That They Cannot Handle"</i>'))
    elems.append(space(5))

    elems.append(section_header("CLINICAL CORRELATIONS", RED))
    elems.append(clinical_note("<b>Colles' fracture</b>: distal radius, dorsal displacement → 'dinner fork deformity'. FOOSH in elderly women (osteoporosis). Radial nerve at risk."))
    elems.append(clinical_note("<b>Smith's fracture</b>: reverse Colles' — volar displacement. Direct blow to dorsal wrist."))
    elems.append(clinical_note("<b>Scaphoid fracture</b>: most commonly fractured carpal bone (FOOSH). Risk of AVN (blood supply enters distally). Anatomical snuffbox tenderness. May be occult on initial X-ray."))
    elems.append(clinical_note("<b>TFCC injury</b>: ulnar-sided wrist pain, especially with rotation."))
    elems.append(clinical_note("<b>Carpal tunnel syndrome</b>: compression of median nerve under flexor retinaculum → thenar wasting + 'ape hand'."))

    elems.append(PageBreak())

    # ── 4. HAND JOINTS ─────────────────────────────────────────────────────────
    elems.append(joint_header(4, "JOINTS OF THE HAND", "CMC • MCP • IP Joints", colors.HexColor("#c89a2a")))
    elems.append(space(6))

    hand_data = [
        ["Joint", "Type", "Movements", "Key Features"],
        ["Thumb CMC (1st carpometacarpal)", "Saddle (sellar)", "Flex, Ext, Abd, Add, Opposition", "Most mobile CMC; thumb opposition unique to primates"],
        ["Fingers CMC (2nd-5th)", "Plane (gliding)", "Limited gliding", "2nd & 3rd almost immobile; 4th & 5th slight mobility"],
        ["MCP joints (knuckles)", "Condyloid", "Flex, Ext, Abd, Add", "Collateral ligs taut in flexion; palmar plates prevent hyperext"],
        ["PIP joints", "Hinge", "Flexion & Extension only", "Most important for grip; commonly injured"],
        ["DIP joints", "Hinge", "Flexion & Extension only", "Mallet finger = extensor tendon injury here"],
    ]
    elems.append(make_table(hand_data, col_widths=[avail_w*0.28, avail_w*0.16, avail_w*0.24, avail_w*0.32],
                            hdr_color=GOLD, alt_color=LIGHT_GOLD))
    elems.append(space(5))

    elems.append(section_header("CLINICAL CORRELATIONS", RED))
    elems.append(clinical_note("<b>Mallet finger:</b> rupture of extensor tendon at DIP → fixed flexion deformity of distal phalanx"))
    elems.append(clinical_note("<b>Boutonniere deformity:</b> central slip of extensor tendon at PIP ruptures → PIP flexion + DIP hyperextension"))
    elems.append(clinical_note("<b>Swan neck deformity:</b> PIP hyperextension + DIP flexion (rheumatoid arthritis)"))
    elems.append(clinical_note("<b>Gamekeeper's thumb (skier's thumb):</b> UCL injury of thumb MCP; valgus stress"))
    elems.append(clinical_note("<b>Trigger finger:</b> stenosing tenosynovitis of flexor tendon sheath; finger locks in flexion"))

    elems.append(PageBreak())

    # ══════════════════════════════════════════════════════
    # PART 2: LOWER LIMB JOINTS
    # ══════════════════════════════════════════════════════
    elems.append(PartBanner("PART 2: LOWER LIMB JOINTS",
        "Hip  •  Knee  •  Ankle  •  Foot", ACCENT, avail_w))
    elems.append(space(10))

    # ── 5. HIP JOINT ──────────────────────────────────────────────────────────
    elems.append(joint_header(5, "HIP JOINT", "Synovial Ball & Socket — Stability > Mobility", ACCENT))
    elems.append(space(6))

    diag5 = HipDiagram(avail_w * 0.48, 175)
    hip_basic = [
        ["Feature", "Details"],
        ["Type", "Synovial multiaxial ball & socket"],
        ["Bones", "Head of femur + acetabulum"],
        ["Design emphasis", "Stability & weight-bearing"],
        ["Socket depth", "Deepened by acetabular labrum"],
        ["Labrum function", "Increases articular surface, stabilises"],
        ["Acetabular fossa", "Non-articular; contains fat & lig. teres"],
    ]
    hip_tbl = make_table(hip_basic, col_widths=[avail_w*0.52*0.40, avail_w*0.52*0.60],
                         hdr_color=ACCENT, alt_color=colors.HexColor("#fdecea"))
    combo5 = Table([[diag5, hip_tbl]], colWidths=[avail_w*0.48, avail_w*0.52])
    combo5.setStyle(TableStyle([('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),0),
                                 ('RIGHTPADDING',(0,0),(-1,-1),4)]))
    elems.append(combo5)
    elems.append(space(4))

    elems.append(section_header("LIGAMENTS", ACCENT))
    hip_lig = [
        ["Ligament", "Origin", "Insertion", "Function / Resists"],
        ["Iliofemoral (Y-lig. of Bigelow)", "Ant. inferior iliac spine", "Intertrochanteric line", "Resists hyperextension; STRONGEST lig. in body"],
        ["Pubofemoral", "Pubic part of acetabular rim", "Intertrochanteric line (ant.)", "Limits abduction & extension"],
        ["Ischiofemoral", "Posterior acetabular rim", "Greater trochanter (base)", "Limits medial rotation; winds capsule in extension"],
        ["Ligamentum teres (intracapsular)", "Acetabular fossa / transverse lig.", "Fovea of femoral head", "Minor stabiliser; carries small obturator artery branch"],
    ]
    elems.append(make_table(hip_lig, col_widths=[avail_w*0.27, avail_w*0.22, avail_w*0.22, avail_w*0.29],
                            hdr_color=ACCENT, alt_color=LIGHT_RED))
    elems.append(space(4))

    elems.append(section_header("BLOOD SUPPLY TO FEMORAL HEAD (CRITICAL)", RED))
    elems.append(body("<b>1. Medial circumflex femoral artery (MCFA)</b> — main supply; enters posteriorly via retinacular vessels"))
    elems.append(body("<b>2. Lateral circumflex femoral artery (LCFA)</b> — minor contribution"))
    elems.append(body("<b>3. Obturator artery</b> via ligamentum teres — minimal contribution (only in children)"))
    elems.append(body("<b>Trochanteric anastomosis</b>: ring of vessels around femoral neck from MCFA + LCFA branches"))
    elems.append(space(4))

    elems.append(section_header("CLINICAL CORRELATIONS", RED))
    elems.append(clinical_note("<b>Neck of femur fracture</b>: disrupts MCFA → avascular necrosis (AVN) of femoral head. Elderly females with osteoporosis. Intracapsular (Garden I-IV) vs extracapsular."))
    elems.append(clinical_note("<b>Posterior dislocation</b> (most common, 90%): high-energy trauma (dashboard injury). Limb: flexed, adducted, internally rotated. Risk of sciatic nerve injury."))
    elems.append(clinical_note("<b>Perthes disease</b>: idiopathic AVN femoral head in children 4-8 years (boys > girls). Self-limiting but may cause deformity."))
    elems.append(clinical_note("<b>DDH (developmental dysplasia)</b>: shallow acetabulum; Ortolani & Barlow tests; treated with Pavlik harness."))
    elems.append(clinical_note("<b>Trendelenburg sign (+)</b>: pelvis drops on unsupported side when standing on one leg = gluteus medius weakness (superior gluteal nerve injury / hip OA / coxa vara)."))
    elems.append(clinical_note("<b>Thomas test</b>: fixed flexion deformity of hip; <b>FABER/FADIR</b> tests for hip pathology."))

    elems.append(PageBreak())

    # ── 6. KNEE JOINT ──────────────────────────────────────────────────────────
    elems.append(joint_header(6, "KNEE JOINT", "Largest Synovial Joint — Modified Hinge", colors.HexColor("#1a3a6b")))
    elems.append(space(6))

    diag6 = KneeDiagram(avail_w * 0.46, 175)
    knee_basic = [
        ["Feature", "Details"],
        ["Type", "Synovial modified hinge (condylar)"],
        ["Articulatons", "Tibiofemoral + Patellofemoral"],
        ["Size", "Largest joint in the body"],
        ["Patella role", "Sesamoid; increases mechanical advantage of quad"],
        ["Locking mech.", "Lateral tibial rotation (screw-home) in full ext."],
        ["Unlocking", "Popliteus muscle (medially rotates tibia)"],
    ]
    knee_tbl = make_table(knee_basic, col_widths=[avail_w*0.54*0.36, avail_w*0.54*0.64],
                          hdr_color=DARK_BLUE, alt_color=LIGHT_BLUE)
    combo6 = Table([[diag6, knee_tbl]], colWidths=[avail_w*0.46, avail_w*0.54])
    combo6.setStyle(TableStyle([('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),0),
                                 ('RIGHTPADDING',(0,0),(-1,-1),4)]))
    elems.append(combo6)
    elems.append(space(4))

    elems.append(section_header("MENISCI", DARK_BLUE))
    menisci_data = [
        ["Feature", "Medial Meniscus", "Lateral Meniscus"],
        ["Shape", "C-shaped (larger, more open)", "O-shaped (smaller, more circular)"],
        ["Attachment to capsule", "Firmly attached to tibial collateral ligament & capsule", "NOT attached to fibular collateral ligament; loose"],
        ["Mobility", "Less mobile → more commonly torn", "More mobile → less commonly torn"],
        ["Transverse lig.", "Connected anteriorly by transverse ligament of knee", ""],
        ["Extra connection", "Coronary ligament to tibia", "Posterior horn: ligament of Wrisberg to medial fem. condyle"],
    ]
    elems.append(make_table(menisci_data, col_widths=[avail_w*0.22, avail_w*0.39, avail_w*0.39],
                            hdr_color=DARK_BLUE, alt_color=LIGHT_BLUE))
    elems.append(space(4))

    elems.append(section_header("LIGAMENTS", DARK_BLUE))
    knee_lig = [
        ["Ligament", "Attachment", "Taut When", "Resists / Function"],
        ["Tibial (MCL) collateral", "Med. fem. epicondyle → medial tibia", "Flexion & Extension", "Valgus stress; attached to medial meniscus"],
        ["Fibular (LCL) collateral", "Lat. fem. epicondyle → head of fibula", "Extension", "Varus stress; NOT attached to lateral meniscus"],
        ["ACL (ant. cruciate)", "Ant. tibial intercondylar area → post. lat. fem. condyle", "Extension", "Prevents ant. tibial displacement; prevents hyperextension"],
        ["PCL (post. cruciate)", "Post. tibial intercondylar → ant. med. fem. condyle", "Flexion", "Prevents post. tibial displacement; stronger than ACL"],
        ["Patellar ligament", "Apex of patella → tibial tuberosity", "—", "Continuation of quad tendon; transmits extensor force"],
    ]
    elems.append(make_table(knee_lig, col_widths=[avail_w*0.22, avail_w*0.26, avail_w*0.18, avail_w*0.34],
                            hdr_color=DARK_BLUE, alt_color=LIGHT_BLUE))
    elems.append(space(4))

    elems.append(section_header("BURSAE", DARK_BLUE))
    bursae_data = [
        ["Bursa", "Location", "Clinical Significance"],
        ["Prepatellar bursa", "Between patella and skin", "Housemaid's knee (kneeling); bursitis"],
        ["Superficial infrapatellar", "Between tibial tuberosity and skin", "Clergyman's knee (on all fours)"],
        ["Deep infrapatellar", "Between patellar ligament and tibia", "Clergyman's knee"],
        ["Semimembranosus bursa", "Posterior, between semimembranosus & med. head gastrocnemius", "Baker's cyst (communicates with joint in adults)"],
        ["Suprapatellar pouch", "Communicates with knee joint cavity", "Effusion visible / palpable above patella"],
    ]
    elems.append(make_table(bursae_data, col_widths=[avail_w*0.28, avail_w*0.32, avail_w*0.40],
                            hdr_color=MED_BLUE, alt_color=LIGHT_BLUE))
    elems.append(space(4))

    elems.append(section_header("CLINICAL TESTS & CORRELATIONS", RED))
    tests_data = [
        ["Test / Condition", "Technique", "Positive Result / Significance"],
        ["Lachman's test (ACL)", "Tibia pulled forward at 15-30° flexion", "Anterior tibial displacement = ACL tear (most sensitive)"],
        ["Anterior drawer test (ACL)", "Tibia pulled forward at 90° flexion", "Anterior displacement = ACL tear"],
        ["Posterior drawer test (PCL)", "Tibia pushed back at 90° flexion", "Posterior displacement = PCL tear"],
        ["McMurray's test", "Knee flex/ext with valgus + rotation", "Click = meniscal tear"],
        ["Valgus stress test (MCL)", "Valgus force at 30° flexion", "Pain/laxity = MCL tear"],
        ["Unhappy triad (O'Donoghue)", "Valgus force on flexed knee", "ACL + MCL + Medial meniscus torn"],
    ]
    elems.append(make_table(tests_data, col_widths=[avail_w*0.27, avail_w*0.32, avail_w*0.41],
                            hdr_color=RED, alt_color=LIGHT_RED))

    elems.append(PageBreak())

    # ── 7. ANKLE JOINT ─────────────────────────────────────────────────────────
    elems.append(joint_header(7, "ANKLE (TALOCRURAL) JOINT", "Synovial Hinge — Mortise & Tenon", PURPLE))
    elems.append(space(6))

    diag7 = AnkleDiagram(avail_w * 0.46, 165)
    ankle_basic = [
        ["Feature", "Details"],
        ["Type", "Synovial hinge joint"],
        ["Bones", "Distal tibia + fibula (mortise) + talus"],
        ["Mortise", "Medial malleolus + lateral malleolus + tibial plafond"],
        ["Movements", "Dorsiflexion (tibialis ant.) & Plantarflexion (gastrocnemius/soleus)"],
        ["Most stable position", "Dorsiflexion (wide ant. talus fills mortise tightly)"],
        ["Most vulnerable position", "Plantarflexion (narrow post. talus = less stable)"],
    ]
    ankle_tbl = make_table(ankle_basic, col_widths=[avail_w*0.54*0.36, avail_w*0.54*0.64],
                           hdr_color=PURPLE, alt_color=LIGHT_PURPLE)
    combo7 = Table([[diag7, ankle_tbl]], colWidths=[avail_w*0.46, avail_w*0.54])
    combo7.setStyle(TableStyle([('VALIGN',(0,0),(-1,-1),'TOP'),('LEFTPADDING',(0,0),(-1,-1),0),
                                 ('RIGHTPADDING',(0,0),(-1,-1),4)]))
    elems.append(combo7)
    elems.append(space(4))

    elems.append(section_header("LIGAMENTS", PURPLE))
    ankle_lig = [
        ["Ligament", "Side", "Parts", "Function"],
        ["Deltoid (medial) ligament", "Medial", "Tibionavicular, Ant. tibiotalar, Post. tibiotalar, Tibiocalcaneal", "Very strong; resists eversion; rarely torn alone"],
        ["ATFL (ant. talofibular lig.)", "Lateral", "Single band", "Resists plantarflexion + inversion; MOST COMMONLY TORN"],
        ["CFL (calcaneofibular lig.)", "Lateral", "Single band", "Resists inversion with foot neutral"],
        ["PTFL (post. talofibular lig.)", "Lateral", "Strongest lateral lig.", "Resists extreme dorsiflexion & internal rotation; rarely torn"],
    ]
    elems.append(make_table(ankle_lig, col_widths=[avail_w*0.26, avail_w*0.10, avail_w*0.36, avail_w*0.28],
                            hdr_color=PURPLE, alt_color=LIGHT_PURPLE))
    elems.append(space(4))

    elems.append(section_header("CLINICAL CORRELATIONS", RED))
    elems.append(clinical_note("<b>Lateral ankle sprain</b>: most common ankle injury; ATFL torn first (plantarflexion + inversion). Ottawa ankle rules guide X-ray decision."))
    elems.append(clinical_note("<b>Pott's fracture</b>: bimalleolar (both malleoli) or trimalleolar (+ posterior tibial margin) fracture-dislocation"))
    elems.append(clinical_note("<b>High ankle sprain</b>: syndesmosis injury (anterior tibiofibular ligament); often missed; mechanism = external rotation"))
    elems.append(clinical_note("<b>Achilles tendon rupture</b>: Simmond's/Thompson test positive (squeeze calf → no plantarflexion)"))
    elems.append(clinical_note("<b>Talus fractures</b>: risk of AVN (blood supply from three vessels entering at neck/sinus tarsi)"))

    elems.append(PageBreak())

    # ── 8. FOOT JOINTS ─────────────────────────────────────────────────────────
    elems.append(joint_header(8, "SUBTALAR & FOOT JOINTS", "Inversion • Eversion • Arches", colors.HexColor("#1a7a4a")))
    elems.append(space(6))

    foot_data = [
        ["Joint", "Type", "Bones", "Main Movements", "Key Feature"],
        ["Subtalar (talocalcaneal)", "Plane synovial", "Talus + calcaneus", "Inversion & eversion", "3 facets; supported by interosseous talocalcaneal ligament"],
        ["Talonavicular", "Ball & socket (part of midtarsal)", "Talus + navicular", "Inversion, eversion, adduction", "With calcaneocuboid = transverse tarsal joint"],
        ["Calcaneocuboid", "Saddle (part of midtarsal)", "Calcaneus + cuboid", "Limited gliding", "Key component of lateral column of foot"],
        ["Tarsometatarsal (Lisfranc)", "Plane synovial", "Tarsals + metatarsal bases", "Minimal gliding", "Lisfranc ligament (2nd TMT); injury commonly missed"],
        ["MTP joints", "Condyloid synovial", "Metatarsals + proximal phalanges", "Flex, ext, abd, add", "1st MTP = hallux valgus (bunion) site"],
        ["IP joints (toe)", "Hinge synovial", "Phalanges", "Flexion, extension", "Hammer toe = PIP flexion deformity"],
    ]
    elems.append(make_table(foot_data, col_widths=[avail_w*0.20, avail_w*0.16, avail_w*0.18, avail_w*0.16, avail_w*0.30],
                            hdr_color=colors.HexColor("#1a7a4a"), alt_color=LIGHT_GREEN))
    elems.append(space(6))

    elems.append(section_header("ARCHES OF THE FOOT", colors.HexColor("#1a7a4a")))
    arches = [
        ["Arch", "Bones", "Keystone", "Main Support"],
        ["Medial longitudinal (higher)", "Calcaneus - talus - navicular - cuneiforms - 1st-3rd MT", "Talus", "Spring (plantar calcaneonavicular) ligament + tibialis posterior + FHL"],
        ["Lateral longitudinal (lower)", "Calcaneus - cuboid - 4th-5th MT", "Cuboid", "Long & short plantar ligaments + peroneus longus"],
        ["Transverse arch", "Cuboid + 3 cuneiforms + bases of MT", "2nd cuneiform", "Peroneus longus (crosses obliquely)"],
    ]
    elems.append(make_table(arches, col_widths=[avail_w*0.24, avail_w*0.36, avail_w*0.12, avail_w*0.28],
                            hdr_color=colors.HexColor("#1a7a4a"), alt_color=LIGHT_GREEN))
    elems.append(space(6))

    elems.append(section_header("CLINICAL CORRELATIONS", RED))
    elems.append(clinical_note("<b>Pes planus (flat foot)</b>: loss of medial longitudinal arch; spring ligament laxity; posterior tibial tendon dysfunction"))
    elems.append(clinical_note("<b>Pes cavus (high arch)</b>: exaggerated medial arch; associated with Charcot-Marie-Tooth disease & Friedreich's ataxia"))
    elems.append(clinical_note("<b>Hallux valgus (bunion)</b>: lateral deviation of great toe at 1st MTP; female predominance; ill-fitting shoes"))
    elems.append(clinical_note("<b>Lisfranc injury</b>: disruption of tarsometatarsal joints; mechanism = axial load on plantarflexed foot; commonly missed on X-ray"))
    elems.append(clinical_note("<b>Plantar fasciitis</b>: inflammation at calcaneal attachment of plantar fascia; heel pain worst in morning"))
    elems.append(clinical_note("<b>Morton's neuroma</b>: perineural fibrosis of common digital nerve (3rd-4th interspace most common)"))

    elems.append(PageBreak())

    # ══════════════════════════════════════════════════════
    # SUMMARY COMPARISON TABLE
    # ══════════════════════════════════════════════════════
    elems.append(PartBanner("MASTER SUMMARY TABLES", "Quick Reference for Revision", MED_BLUE, avail_w))
    elems.append(space(10))

    elems.append(sub_header("All Joints at a Glance"))
    summary = [
        ["Joint", "Type", "Key Movements", "Key Nerve", "Common Problem"],
        ["Shoulder", "Ball & socket", "All (most mobile)", "Axillary (C5,C6)", "Anterior dislocation"],
        ["Elbow", "Compound hinge+pivot", "Flex/Ext + Pro/Sup", "Radial nerve", "Supracondylar # (child)"],
        ["Wrist", "Condyloid", "Flex/Ext + Deviation", "Ant. interosseous", "Colles' fracture"],
        ["Hand CMC/MCP/IP", "Various", "Flex/Ext, Opposition", "Median/Ulnar", "Mallet, Boutonniere"],
        ["Hip", "Ball & socket", "All (most stable)", "Femoral/Obturator/Sciatic", "NOF # → AVN"],
        ["Knee", "Modified hinge", "Flex/Ext + Rotation", "Femoral/Sciatic", "ACL + Meniscal tear"],
        ["Ankle", "Hinge", "Dorsiflex/Plantarflex", "Tibial + Deep peroneal", "Lateral sprain (ATFL)"],
        ["Foot", "Multiple types", "Inversion/Eversion", "Tibial + Peroneal", "Hallux valgus, Flat foot"],
    ]
    elems.append(make_table(summary,
        col_widths=[avail_w*0.14, avail_w*0.18, avail_w*0.20, avail_w*0.22, avail_w*0.26]))
    elems.append(space(10))

    elems.append(sub_header("Nerve Supply Summary"))
    nerves = [
        ["Joint", "Nerve(s)", "Spinal Level", "Hilton's Law Note"],
        ["Shoulder", "Axillary, suprascapular, lat. pectoral", "C5, C6", "Muscles acting on + nerve crossing over joint"],
        ["Elbow", "Radial (main), musculocutaneous, median, ulnar", "C5-T1", "All main arm nerves contribute"],
        ["Wrist/Hand", "Radial, median, ulnar (ant. & post. interosseous)", "C6-T1", "Median = thumb/index/middle; Ulnar = ring/little"],
        ["Hip", "Femoral, obturator, sciatic, sup. gluteal", "L2-S1", "Knee pain may be referred from hip (obturator)"],
        ["Knee", "Femoral, obturator, common peroneal, tibial", "L2-S2", "Obturator → explains hip OA causing knee pain"],
        ["Ankle/Foot", "Deep peroneal (dorsum), tibial (sole), sural", "L4-S2", "Tibial nerve = intrinsic muscles of sole"],
    ]
    elems.append(make_table(nerves,
        col_widths=[avail_w*0.12, avail_w*0.30, avail_w*0.14, avail_w*0.44],
        hdr_color=GREEN, alt_color=LIGHT_GREEN))
    elems.append(space(10))

    elems.append(sub_header("Blood Supply Summary"))
    blood = [
        ["Joint", "Main Artery", "Source", "Clinical Note"],
        ["Shoulder", "Ant. & Post. circumflex humeral", "Axillary artery", "Surgical neck # → anterior circumflex at risk"],
        ["Elbow", "Anastomotic network", "Brachial + Radial + Ulnar", "Network = collateral circulation preserved in distal occlusion"],
        ["Wrist", "Dorsal + palmar carpal arches", "Radial + Ulnar", "Scaphoid fracture → AVN (distal to proximal supply)"],
        ["Hip", "Medial circumflex femoral (main)", "Profunda femoris", "NOF # disrupts MCFA → AVN femoral head"],
        ["Knee", "Genicular branches", "Femoral + Popliteal + Ant. tibial", "Rich anastomosis above and below joint"],
        ["Ankle/Foot", "Ant. tibial, post. tibial, peroneal", "Popliteal artery", "Talus AVN after fracture (poor supply at neck)"],
    ]
    elems.append(make_table(blood,
        col_widths=[avail_w*0.12, avail_w*0.25, avail_w*0.18, avail_w*0.45],
        hdr_color=ACCENT, alt_color=LIGHT_RED))
    elems.append(space(10))

    # ── Footer note
    elems.append(hr())
    elems.append(Paragraph(
        "BDC Anatomy Joint Notes | Source: Gray's Anatomy for Students | For educational purposes only",
        S['footer']))

    # ── Build PDF
    doc.build(elems)
    print(f"PDF created: {path}")
    return path

if __name__ == "__main__":
    build()
Running Command

cd /tmp/workspace/joint-notes-pdf && python generate_pdf.py 2>&1

Editing File

~/joint-notes-pdf/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/joint-notes-pdf/generate_pdf.py'
Running Command

cd /tmp/workspace/joint-notes-pdf && python generate_pdf.py 2>&1

Editing File

~/joint-notes-pdf/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/joint-notes-pdf/generate_pdf.py'
Running Command

cd /tmp/workspace/joint-notes-pdf && python generate_pdf.py 2>&1

Running Command

grep -n "c\.polygon\|c\.poly" /tmp/workspace/joint-notes-pdf/generate_pdf.py

Reading File
Reading File
Reading File
Editing File

~/joint-notes-pdf/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/joint-notes-pdf/generate_pdf.py'
Editing File

~/joint-notes-pdf/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/joint-notes-pdf/generate_pdf.py'
Editing File

~/joint-notes-pdf/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/joint-notes-pdf/generate_pdf.py'
Running Command

cd /tmp/workspace/joint-notes-pdf && python generate_pdf.py 2>&1

Running Command

ls -lh /tmp/workspace/joint-notes-pdf/BDC_Joint_Notes.pdf

[Called write_todos with parameters: {"todos": [{"content": "Read PDF skill reference.md for advanced ReportLab examples", "status": "completed"}, {"content": "Create workspace directory and write Python PDF generation script", "status": "completed"}, {"content": "Execute the script to generate the PDF with diagrams/tables", "status": "completed"}, {"content": "Verify PDF output and provide download link", "status": "completed"}]}]
Your PDF has been generated successfully! Here is the download link:

BDC Joint Notes

PDF Document · PDF


What's inside the PDF (41 KB, multi-page A4):
Cover Page
  • Dark blue professional cover with title, joint list, and 4 feature badges
Part 1 - Upper Limb Joints (4 joints)
  1. Shoulder (Glenohumeral) - Schematic diagram + Rotator cuff SITS table + Ligament table + Clinical notes (Bankart, Hill-Sachs, frozen shoulder)
  2. Elbow - Schematic diagram + 3-articulation table + Ligament table + Clinical notes (supracondylar #, fat pad sign, nursemaid's elbow)
  3. Wrist (Radiocarpal) - Overview table + Ligament table + Carpal mnemonic + Clinical notes (Colles', scaphoid #, CTS)
  4. Hand Joints - CMC/MCP/IP table + Clinical notes (mallet finger, boutonniere, swan neck)
Part 2 - Lower Limb Joints (4 joints) 5. Hip - Schematic diagram + Ligament table + Blood supply to femoral head + Clinical notes (NOF #, AVN, Perthes, DDH, Trendelenburg) 6. Knee - Schematic diagram + Menisci comparison table + Ligament table + Bursae table + Clinical tests table (Lachman, drawer, McMurray, unhappy triad) 7. Ankle - Schematic diagram + Ligament table (Deltoid, ATFL, CFL, PTFL) + Clinical notes (sprains, Pott's, Achilles) 8. Foot - All foot joints table + Arches of foot table + Clinical notes (flat foot, hallux valgus, Lisfranc)
Master Summary Tables
  • All 8 joints at a glance
  • Nerve supply summary
  • Blood supply summary
This is a shared conversation. Sign in to Orris to start your own chat.