paediatric distal radius fractures

Reading File
Finding Sources
Searching PubMed

"distal radius fracture"[MeSH Terms] AND child[MeSH Terms]

Searching the Web

paediatric distal radius fractures management classification 2024 guidelines

Finding Sources
Finding Sources
Searching PubMed

"radius fracture" AND "children" AND "treatment"

Finding Sources
Finding Sources
Reading Web Page

https://www.ncbi.nlm.nih.gov/books/NBK536916

Finding Sources
Reading File
Finding Sources
Finding Sources
Finding Sources
Searching the Web

paediatric distal radius fracture acceptable angulation remodeling potential K-wire indications 2024

Reading Web Page

https://www.sicot-j.org/articles/sicotj/full_html/2026/01/si…

I now have comprehensive material to write a thorough, well-structured answer. Here it is:

Paediatric Distal Radius Fractures

Epidemiology

The distal radius is the single most common fracture site in children, accounting for approximately 35-45% of all paediatric fractures. The mechanism is almost invariably a FOOSH (fall on an outstretched hand). Boys are affected more frequently than girls. Peak incidence is in the 6-14 year age group, coinciding with periods of rapid growth when the physis is relatively weak compared to surrounding bone.

Unique Paediatric Considerations

Children's bones differ from adults in ways that directly shape management:
  • Periosteum - thick and active; aids reduction and helps maintain it
  • Remodeling potential - the distal radial physis contributes ~75% of longitudinal radial growth, giving enormous capacity to correct residual deformity, especially in younger children and in the sagittal plane (the plane of wrist motion)
  • Plasticity - immature bone can deform without discrete cortical failure (plastic/bowing deformity)
  • Growth plate vulnerability - the physis is the weakest point under stress; Salter-Harris injuries are common
  • Remodeling is age- and plane-dependent - greater tolerance in younger children; sagittal-plane angulation corrects better than coronal or rotational deformity

Fracture Classification

Morphological Types (metaphyseal - most common)

TypeDescriptionStability
Torus (buckle)Axial compression buckles the metaphyseal cortex; cortical continuity preservedStable
GreenstickTension-side cortex fails; compression-side intact; may have angulationPartially stable
CompleteBoth cortices disrupted; may be displaced, translated, or bayonetedUnstable
Plastic deformationBone bends without discrete fracture line (more common in ulna)Stable

Physeal Injuries - Salter-Harris Classification

TypePatternFrequency at Distal RadiusGrowth Disturbance Risk
SH IThrough physis onlyCommonRare
SH IIThrough physis + metaphysis (Thurston-Holland fragment)Most commonRare
SH IIIThrough physis + epiphysis (intra-articular)RareMedium
SH IVThrough metaphysis + physis + epiphysisRareHigh
SH VCrush injury of physisVery rareHigh
SH types I and II account for the vast majority of physeal injuries and carry an excellent prognosis. SH III and IV are intra-articular and require anatomic reduction.

Imaging

  • Standard AP and lateral wrist radiographs are the first-line investigation
  • The lateral view is critical to assess dorsal/volar angulation and DRUJ alignment
  • Associated ulnar styloid fracture is common and usually requires no specific treatment
  • Check for DRUJ instability (Galeazzi pattern) in shaft fractures
  • CT or MRI are not routinely required but may assist with intra-articular SH III/IV fractures

Acceptable Reduction Parameters

Remodeling potential is highest in younger children with fractures close to the physis and in the sagittal plane. The following angulation limits are most widely cited (Noonan and Price criteria):

By Age Group

ParameterUnder 10 years (or girls ≤8, boys ≤10)Over 10 years (or girls >8, boys >10)
Sagittal angulation≤20-30°≤15°
Coronal angulation≤10°≤10°
Rotation≤15°≤30° (functional)
Bayonet appositionUp to 1 cm acceptable in <11 yearsUp to 1 cm
  • Angulation >10° in the distal third causes approximately 20° of lost pronation-supination arc
  • Rotational malalignment is not corrected by remodeling - keep rotation within accepted limits
  • In patients approaching skeletal maturity, near-anatomic reduction is preferred

Management

1. Torus (Buckle) Fractures

  • Stable by definition; will not displace
  • Treatment: removable splint or soft cast for 3-4 weeks
  • No reduction required
  • No routine fracture clinic follow-up needed if truly isolated torus fracture (evidence supports discharge with return-to-sport at 3-4 weeks)
  • Parent education and instruction to return if concerns arise

2. Greenstick Fractures

  • Conservative management; splint then short arm cast for 4-6 weeks
  • Minimally displaced/undisplaced: cast without reduction
  • If angulation exceeds age-appropriate limits: closed reduction under sedation or GA
  • Acceptance thresholds by age:
    • Under 5 years: up to 35° lateral + 10° AP
    • 5-10 years: up to 25° lateral + 10° AP
    • Over 10 years: <20° lateral + 0° AP

3. Complete Metaphyseal Fractures

  • Non-displaced or minimally displaced: below-elbow cast for 4-6 weeks
  • Displaced: closed reduction and cast (below-elbow or above-elbow)
  • Redisplacement risk is significant (20-35% after casting alone) - particularly in:
    • Initial displacement >50%
    • Bayonet apposition
    • Older children
    • Poor cast technique (cast index >0.8)
  • K-wire fixation reduces redisplacement to 0-5% - indicated for high-risk patterns

4. Physeal (Salter-Harris) Fractures

SH I and II:
  • Undisplaced: below-elbow backslab or removable splint for 4 weeks; fracture clinic within 5 days
  • Displaced: closed reduction + below-elbow backslab for 4 weeks
  • Only one attempt at closed reduction - repeat attempts risk further physeal injury and growth arrest
  • Reduction not advisable after ≥5 days from injury (callus formation)
  • Refer to orthopaedics if closed reduction fails
SH III and IV:
  • Intra-articular - require orthopaedic referral
  • Usually need ORIF to restore articular congruity and physeal alignment
  • Medium-to-high risk of growth disturbance
SH V:
  • Often missed at initial presentation (diagnosed retrospectively from growth arrest)
  • Very high risk of growth disturbance

Surgical Indications

Prompt orthopaedic referral/surgery is indicated for:
  • Failed closed reduction or inability to maintain reduction in cast
  • Neurovascular compromise (median nerve is most at risk - anterior interosseous nerve injury can occur)
  • Open fractures
  • Compartment syndrome
  • SH III, IV, V fractures
  • Irreducible fractures (soft tissue interposition)
  • Fractures in skeletally mature adolescents where remodeling is limited

Surgical Options

TechniqueIndication
Percutaneous K-wire (transphyseal or intrafocal/Kapandji)Unstable metaphyseal or SH II fractures; first-line surgical option
Intrafocal (Kapandji) K-wirePreferred for SH II - avoids transphyseal pin damage to growth plate
Elastic intramedullary nails (TENS/ESIN)Unstable diaphyseal/distal shaft fractures; higher morbidity than K-wires
Open reduction + internal fixation (plate/screw)SH III/IV intra-articular fractures; irreducible fractures; near-skeletal maturity

Cast Technique Considerations

  • Below-elbow (short arm) cast is standard for most distal metaphyseal and physeal fractures
  • Above-elbow cast may be used for unstable fractures or in younger children to control rotation
  • Cast index should be ≤0.7 to reduce redisplacement risk
  • Adequate 3-point moulding reduces loss of reduction
  • RCT evidence shows above- and below-elbow casts have similar outcomes for distal forearm fractures

Complications

ComplicationComment
RedisplacementMost common complication; 20-35% in casted metaphyseal fractures
MalunionUsually well-tolerated in young children due to remodeling; significant in older patients
Growth disturbance/growth arrestRisk increases with SH grade; also increased with delayed reduction (>3 days), repeat reduction attempts
RefractureMore common after removal of immobilisation; protective splinting during high-risk activities
Median/anterior interosseous nerve injuryUsually neuropraxia; resolves spontaneously
DRUJ instabilityAssociated with Galeazzi-equivalent injuries in children
Compartment syndromeRare but must be excluded in displaced fractures
Physeal arrestLate complication of SH V or undertreated physeal injuries; may cause progressive deformity

Current Evidence Framework (SICOT-J 2026)

A 2026 systematic review (45 studies, 5,340 patients) confirmed:
  • Metaphyseal pathway: Stable fractures (torus) require minimal intervention. Displaced-but-stable fractures are managed with closed reduction and molded casting. K-wire fixation is reserved for high-risk patterns - it reduces redisplacement from 20-35% to 0-5%.
  • Physeal pathway: Prioritise growth plate preservation. Intrafocal (Kapandji) K-wire pinning is preferred for unstable SH II injuries, as it provides rigid fixation while avoiding transphyseal iatrogenic injury.
  • Elastic intramedullary nailing and plating carry greater implant-related morbidity and should be reserved for specific indications (irreducible, intra-articular, or near-mature fractures).
  • Cast-related complications primarily reflect mechanical failure; K-wire complications are typically minor and self-limited.

Key Practical Points

  1. Age matters more than angulation alone - a 7-year-old can remodel 20-25° of dorsal angulation; a 14-year-old cannot
  2. One attempt at physeal reduction only - repeat manipulation significantly increases growth arrest risk
  3. Torus fractures are stable - simple splinting is sufficient; no reduction needed
  4. Rotational deformity does not remodel - must be corrected at time of reduction
  5. Follow-up is mandatory for displaced fractures - redisplacement peaks at 1-2 weeks
  6. Bayonet apposition is acceptable in children under 11 with good remodeling potential
  7. Galeazzi equivalent - in children, a distal radius fracture with DRUJ disruption may manifest as a physeal injury (SH I/II of the distal ulna rather than a ligamentous injury)

Create a quick reference PDF on paediatric distal radius fracture reduction parameters and management algorithm

Reading File
Running Command

ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or does not exist"

Running Command

mkdir -p /home/daytona/workspace/paeds-radius-pdf && python3 -c "import reportlab; print('reportlab ok')" && python3 -c "from reportlab.lib import colors; print('colors ok')"

Writing File

~/paeds-radius-pdf/build_pdf.py

"""
Paediatric Distal Radius Fracture - Quick Reference PDF
Uses ReportLab to produce a clean, colour-coded 2-page reference card.
"""

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import Flowable
from reportlab.pdfbase import pdfmetrics

OUTPUT = "/home/daytona/workspace/paeds-radius-pdf/Paeds_Distal_Radius_QR.pdf"

# ── Colour palette ─────────────────────────────────────────────────────────────
NAVY      = colors.HexColor("#1A3557")
TEAL      = colors.HexColor("#1B7A8C")
ORANGE    = colors.HexColor("#E85D04")
GREEN     = colors.HexColor("#2D6A4F")
RED       = colors.HexColor("#C1121F")
AMBER     = colors.HexColor("#E9A900")
LTBLUE    = colors.HexColor("#D6EAF8")
LTTEAL    = colors.HexColor("#D0EEF2")
LTGREEN   = colors.HexColor("#D8F3DC")
LTORANGE  = colors.HexColor("#FFF0E0")
LTRED     = colors.HexColor("#FDECEA")
LTAMBER   = colors.HexColor("#FFF8E1")
VLTGREY   = colors.HexColor("#F7F9FB")
MIDGREY   = colors.HexColor("#95A5A6")
WHITE     = colors.white
BLACK     = colors.black


# ── Custom horizontal rule ─────────────────────────────────────────────────────
class ColoredHR(Flowable):
    def __init__(self, width, color, thickness=0.8):
        Flowable.__init__(self)
        self.width = width
        self.color = color
        self.thickness = thickness
        self.height = thickness + 1

    def draw(self):
        self.canv.setStrokeColor(self.color)
        self.canv.setLineWidth(self.thickness)
        self.canv.line(0, 0, self.width, 0)


# ── Section header helper ──────────────────────────────────────────────────────
def section_header(text, color=NAVY, bg=LTBLUE, width=170*mm):
    style = ParagraphStyle(
        "SH", fontName="Helvetica-Bold", fontSize=9.5,
        textColor=WHITE, leading=14, leftIndent=5, spaceBefore=2
    )
    data = [[Paragraph(text, style)]]
    t = Table(data, colWidths=[width])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, -1), color),
        ("TOPPADDING",    (0, 0), (-1, -1), 4),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 4),
        ("LEFTPADDING",   (0, 0), (-1, -1), 8),
        ("RIGHTPADDING",  (0, 0), (-1, -1), 8),
    ]))
    return t


# ── Body paragraph style ───────────────────────────────────────────────────────
BODY = ParagraphStyle("Body", fontName="Helvetica", fontSize=8, leading=11,
                      textColor=BLACK)
BODYB = ParagraphStyle("BodyB", fontName="Helvetica-Bold", fontSize=8, leading=11,
                       textColor=BLACK)
SMALL = ParagraphStyle("Small", fontName="Helvetica", fontSize=7, leading=10,
                       textColor=BLACK)
SMALLB = ParagraphStyle("SmallB", fontName="Helvetica-Bold", fontSize=7, leading=10,
                        textColor=BLACK)
FOOTNOTE = ParagraphStyle("Footnote", fontName="Helvetica-Oblique", fontSize=6.5,
                          leading=9, textColor=MIDGREY)
TITLE_S = ParagraphStyle("TitleS", fontName="Helvetica-Bold", fontSize=16,
                         leading=20, textColor=WHITE, alignment=TA_CENTER)
SUBTITLE_S = ParagraphStyle("SubS", fontName="Helvetica", fontSize=9,
                             leading=13, textColor=LTBLUE, alignment=TA_CENTER)
HEADER_S = ParagraphStyle("HS", fontName="Helvetica-Bold", fontSize=8.5,
                           leading=12, textColor=NAVY)
WARN = ParagraphStyle("Warn", fontName="Helvetica-BoldOblique", fontSize=7.5,
                      leading=11, textColor=RED)


def sp(n=3):
    return Spacer(1, n)


# ──────────────────────────────────────────────────────────────────────────────
#  BUILD DOCUMENT
# ──────────────────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT, pagesize=A4,
    leftMargin=18*mm, rightMargin=18*mm,
    topMargin=14*mm, bottomMargin=14*mm,
    title="Paediatric Distal Radius Fracture Quick Reference",
    author="Orris Medical"
)

W = A4[0] - 36*mm   # usable width
story = []

# ══════════════════════════════════════════════════════════════════════════════
# TITLE BANNER
# ══════════════════════════════════════════════════════════════════════════════
title_data = [[
    Paragraph("Paediatric Distal Radius Fracture", TITLE_S),
    Paragraph("Quick Reference Card", TITLE_S),
]]
title_table = Table([[
    Paragraph("Paediatric Distal Radius Fracture", TITLE_S),
]], colWidths=[W])
title_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), NAVY),
    ("TOPPADDING", (0,0), (-1,-1), 10),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
]))
story.append(title_table)

sub_table = Table([[
    Paragraph("Reduction Parameters  |  Management Algorithm  |  Salter-Harris Guide", SUBTITLE_S),
]], colWidths=[W])
sub_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), TEAL),
    ("TOPPADDING", (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 6),
]))
story.append(sub_table)
story.append(sp(6))

# ══════════════════════════════════════════════════════════════════════════════
# ROW 1:  Left = Fracture Types   |   Right = Key Principles
# ══════════════════════════════════════════════════════════════════════════════
CW = (W - 4*mm) / 2   # half-width columns with small gap

# ── LEFT: Fracture Types ──────────────────────────────────────────────────────
ft_header = section_header("FRACTURE TYPES", TEAL, LTTEAL, CW)
ft_data = [
    [Paragraph("<b>Type</b>", SMALL), Paragraph("<b>Description</b>", SMALL),
     Paragraph("<b>Stability</b>", SMALL)],
    [Paragraph("Torus\n(Buckle)", SMALL),
     Paragraph("Axial compression; cortical buckling; continuity preserved", SMALL),
     Paragraph("Stable", SMALL)],
    [Paragraph("Greenstick", SMALL),
     Paragraph("Tension cortex fails; compression side intact; angulation", SMALL),
     Paragraph("Partial", SMALL)],
    [Paragraph("Complete", SMALL),
     Paragraph("Both cortices disrupted; may be displaced / bayoneted", SMALL),
     Paragraph("Unstable", SMALL)],
    [Paragraph("Plastic\nDeform.", SMALL),
     Paragraph("Bone bows without discrete fracture line", SMALL),
     Paragraph("Stable", SMALL)],
]
ft_table = Table(ft_data, colWidths=[CW*0.22, CW*0.55, CW*0.23])
ft_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), TEAL),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LTTEAL]),
    ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",   (0,0), (-1,-1), 7),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#BDC3C7")),
    ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))

# ── RIGHT: Key Principles ─────────────────────────────────────────────────────
kp_header = section_header("KEY PAEDIATRIC PRINCIPLES", NAVY, LTBLUE, CW)
kp_bullets = [
    ("Distal radial physis", "contributes 75% of radial longitudinal growth → huge remodeling potential"),
    ("Remodeling inversely", "correlates with age — greatest in young children"),
    ("Sagittal plane", "corrects best (plane of wrist motion); rotational deformity does NOT remodel"),
    ("One reduction attempt", "only for physeal injuries — repeat attempts increase growth arrest risk"),
    ("Bayonet apposition", "acceptable ≤1 cm in children under 11 years"),
    ("Torus fractures", "are stable — no reduction needed; splint 3-4 weeks only"),
    ("Galeazzi equivalent", "in children = distal radius fracture + SH I/II distal ulna (not ligamentous)"),
]
kp_rows = [[
    Paragraph(f"<b>{a}</b>", SMALL),
    Paragraph(b, SMALL)
] for a, b in kp_bullets]
kp_table = Table(kp_rows, colWidths=[CW*0.38, CW*0.62])
kp_table.setStyle(TableStyle([
    ("ROWBACKGROUNDS", (0,0), (-1,-1), [WHITE, LTBLUE]),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#BDC3C7")),
]))

row1 = Table(
    [[ft_header, "", kp_header],
     [ft_table,  "", kp_table]],
    colWidths=[CW, 4*mm, CW]
)
row1.setStyle(TableStyle([
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("LEFTPADDING",  (0,0), (-1,-1), 0),
    ("RIGHTPADDING", (0,0), (-1,-1), 0),
    ("TOPPADDING",   (0,0), (-1,-1), 0),
    ("BOTTOMPADDING",(0,0), (-1,-1), 2),
]))
story.append(row1)
story.append(sp(6))

# ══════════════════════════════════════════════════════════════════════════════
# REDUCTION PARAMETERS TABLE  (full width)
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("ACCEPTABLE REDUCTION PARAMETERS (Noonan & Price Criteria)", ORANGE, LTORANGE, W))
story.append(sp(2))

rp_header_row = [
    Paragraph("<b>Parameter</b>", SMALLB),
    Paragraph("<b>Age &lt;5 yrs</b>", SMALLB),
    Paragraph("<b>Age 5-10 yrs\n(Girls ≤8 / Boys ≤10)</b>", SMALLB),
    Paragraph("<b>Age &gt;10 yrs\n(Girls &gt;8 / Boys &gt;10)</b>", SMALLB),
    Paragraph("<b>Near Skeletal\nMaturity</b>", SMALLB),
]
rp_rows = [
    ["Sagittal (AP) angulation",  "≤35°",  "≤25°",  "≤15°",  "≤10° (anatomic)"],
    ["Coronal angulation",         "≤15°",  "≤10°",  "≤10°",  "≤5°"],
    ["Rotation",                   "≤15°",  "≤15°",  "≤30°",  "Anatomic"],
    ["Bayonet apposition",         "≤1 cm", "≤1 cm", "≤1 cm", "Not acceptable"],
    ["Angulation in distal shaft >10°", "—", "Causes ~20° loss pronation-supination", "→ Reduces function", "Correct"],
]
rp_data = [rp_header_row] + [
    [Paragraph(row[0], SMALL)] + [Paragraph(v, SMALL) for v in row[1:]]
    for row in rp_rows
]
rp_col_w = [W*0.30, W*0.13, W*0.19, W*0.19, W*0.19]
rp_table = Table(rp_data, colWidths=rp_col_w)
rp_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), ORANGE),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LTORANGE]),
    ("FONTSIZE", (0,0), (-1,-1), 7),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#CCCCCC")),
    ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
    ("ALIGN", (1,0), (-1,-1), "CENTER"),
]))
story.append(rp_table)
story.append(sp(6))

# ══════════════════════════════════════════════════════════════════════════════
# ROW 2:  Salter-Harris  |  Greenstick Tolerances
# ══════════════════════════════════════════════════════════════════════════════
# ── LEFT: Salter-Harris Guide ─────────────────────────────────────────────────
sh_header = section_header("SALTER-HARRIS PHYSEAL INJURIES", RED, LTRED, CW)
sh_data = [
    [Paragraph("<b>Type</b>", SMALLB),
     Paragraph("<b>Pattern</b>", SMALLB),
     Paragraph("<b>Freq.</b>", SMALLB),
     Paragraph("<b>Growth Risk</b>", SMALLB),
     Paragraph("<b>Management</b>", SMALLB)],
    ["I",  "Through physis only",              "Common",       "Rare",    "CR + BEP 4 wks"],
    ["II", "Physis + metaphysis (Thurston-Holland)", "Most common", "Rare", "CR + BEP 4 wks;\nintrafocal K-wire if unstable"],
    ["III","Physis + epiphysis (intra-art.)",   "Rare",         "Medium",  "ORIF - refer ortho"],
    ["IV", "Physis + metaphysis + epiphysis",   "Rare",         "HIGH",    "ORIF - refer ortho"],
    ["V",  "Crush injury of physis",             "Very rare",   "VERY HIGH","Often missed;\ngrowth arrest late"],
]
sh_fmt = [
    [Paragraph(row[0], SMALLB if i == 0 else SMALL),
     Paragraph(row[1], SMALL),
     Paragraph(row[2], SMALL),
     Paragraph(row[3], SMALLB if row[3] in ("HIGH","VERY HIGH") else SMALL),
     Paragraph(row[4], SMALL)]
    for i, row in enumerate(sh_data)
]
sh_col_w = [CW*0.07, CW*0.35, CW*0.15, CW*0.16, CW*0.27]
sh_table = Table(sh_fmt, colWidths=sh_col_w)
sh_style = [
    ("BACKGROUND", (0,0), (-1,0), RED),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LTRED]),
    ("FONTSIZE", (0,0), (-1,-1), 7),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#CCCCCC")),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]
# Colour HIGH/VERY HIGH cells
for row_idx, row in enumerate(sh_data[1:], start=1):
    if row[3] in ("HIGH", "VERY HIGH"):
        sh_style.append(("TEXTCOLOR", (3, row_idx), (3, row_idx), RED))
sh_table.setStyle(TableStyle(sh_style))

# ── RIGHT: Greenstick + Torus management ─────────────────────────────────────
gs_header = section_header("METAPHYSEAL FRACTURE MANAGEMENT", GREEN, LTGREEN, CW)
gs_data = [
    [Paragraph("<b>Fracture</b>", SMALLB),
     Paragraph("<b>Management</b>", SMALLB),
     Paragraph("<b>Cast</b>", SMALLB),
     Paragraph("<b>Duration</b>", SMALLB)],
    [Paragraph("Torus\n(Buckle)", SMALL),
     Paragraph("Splint only\nNo reduction", SMALL),
     Paragraph("Removable\nor soft cast", SMALL),
     Paragraph("3-4 wks", SMALL)],
    [Paragraph("Greenstick\n(undisplaced)", SMALL),
     Paragraph("Cast without\nreduction", SMALL),
     Paragraph("Below-elbow", SMALL),
     Paragraph("4-6 wks", SMALL)],
    [Paragraph("Greenstick\n(angulated)", SMALL),
     Paragraph("CR if exceeds\nage limits", SMALL),
     Paragraph("Below-elbow\nmoulded cast", SMALL),
     Paragraph("4-6 wks", SMALL)],
    [Paragraph("Complete\n(non-displaced)", SMALL),
     Paragraph("Cast; no\nreduction", SMALL),
     Paragraph("Below-elbow", SMALL),
     Paragraph("4-6 wks", SMALL)],
    [Paragraph("Complete\n(displaced)", SMALL),
     Paragraph("CR under\nsedation/GA", SMALL),
     Paragraph("Moulded\nBE or AE cast", SMALL),
     Paragraph("4-6 wks", SMALL)],
    [Paragraph("High-risk\ncomplete", SMALL),
     Paragraph("CR + K-wire\npercutaneous", SMALL),
     Paragraph("Above-elbow\ncast", SMALL),
     Paragraph("4-5 wks\n(then remove)", SMALL)],
]
gs_col_w = [CW*0.25, CW*0.30, CW*0.25, CW*0.20]
gs_table = Table(gs_data, colWidths=gs_col_w)
gs_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREEN),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LTGREEN]),
    ("FONTSIZE", (0,0), (-1,-1), 7),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#CCCCCC")),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))

row2 = Table(
    [[sh_header, "", gs_header],
     [sh_table,  "", gs_table]],
    colWidths=[CW, 4*mm, CW]
)
row2.setStyle(TableStyle([
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("LEFTPADDING",  (0,0), (-1,-1), 0),
    ("RIGHTPADDING", (0,0), (-1,-1), 0),
    ("TOPPADDING",   (0,0), (-1,-1), 0),
    ("BOTTOMPADDING",(0,0), (-1,-1), 2),
]))
story.append(row2)
story.append(sp(6))

# ══════════════════════════════════════════════════════════════════════════════
# MANAGEMENT ALGORITHM  (full width)
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("MANAGEMENT ALGORITHM", NAVY, LTBLUE, W))
story.append(sp(2))

# Two-column algorithm: Metaphyseal pathway | Physeal pathway
algo_title_style = ParagraphStyle("AT", fontName="Helvetica-Bold", fontSize=8,
                                  textColor=WHITE, alignment=TA_CENTER, leading=12)
algo_body_style = ParagraphStyle("AB", fontName="Helvetica", fontSize=7.5,
                                 textColor=BLACK, leading=11, leftIndent=4)
algo_bold_style = ParagraphStyle("ABB", fontName="Helvetica-Bold", fontSize=7.5,
                                 textColor=NAVY, leading=11, leftIndent=4)

HCW = (W - 4*mm) / 2

# Metaphyseal
meta_steps = [
    ("DISTAL RADIUS FRACTURE", NAVY),
    ("Is it a PHYSEAL injury?", ORANGE),
    ("NO → Metaphyseal Pathway", TEAL),
    ("Torus/Buckle\n→ Splint 3-4 wks; no reduction; discharge", GREEN),
    ("Greenstick/Complete\n→ Assess angulation vs. age-appropriate limits", TEAL),
    ("Within limits?\n→ Closed reduction under sedation\nMoulded below-elbow cast 4-6 wks", TEAL),
    ("High-Risk Features?\n• Age >10 yrs\n• Initial displacement >50%\n• Bayonet apposition (>11 yrs)\n• Poor cast index (>0.7)\n• Failed reduction", ORANGE),
    ("YES → Percutaneous K-wire fixation\n+ above-elbow cast 4-5 wks", RED),
    ("Follow-up X-ray\nat 1 week\n(peak redisplacement)", NAVY),
]

phy_steps = [
    ("YES → Physeal Pathway", RED),
    ("Salter-Harris I or II", TEAL),
    ("Undisplaced\n→ BEP or removable splint 4 wks\nFracture clinic within 5 days", GREEN),
    ("Displaced\n→ ONE attempt closed reduction\n   + BEP cast 4 wks\n   Refer if unable to reduce", AMBER),
    ("⚠ Do NOT reduce if >5 days old", RED),
    ("⚠ ONE attempt ONLY — repeat\n   attempts → growth arrest risk", RED),
    ("Unstable SH II\n→ Intrafocal (Kapandji) K-wire\n   Avoids transphyseal injury", ORANGE),
    ("Salter-Harris III / IV\n→ Intra-articular\n→ REFER ORTHOPAEDICS\n→ Usually ORIF required", RED),
    ("Salter-Harris V\n→ Often missed acutely\n→ Growth arrest on follow-up\n→ Refer orthopaedics", RED),
]

def algo_box(steps, col_color):
    rows = []
    for text, color in steps:
        style = ParagraphStyle(
            "BS", fontName="Helvetica-Bold" if color in (RED, ORANGE) else "Helvetica",
            fontSize=7, textColor=WHITE if color not in (AMBER,) else BLACK,
            leading=10, leftIndent=4, rightIndent=4, alignment=TA_LEFT
        )
        cell = Table([[Paragraph(text, style)]], colWidths=[HCW - 2*mm])
        cell.setStyle(TableStyle([
            ("BACKGROUND",    (0,0), (-1,-1), color),
            ("TOPPADDING",    (0,0), (-1,-1), 4),
            ("BOTTOMPADDING", (0,0), (-1,-1), 4),
            ("LEFTPADDING",   (0,0), (-1,-1), 6),
            ("RIGHTPADDING",  (0,0), (-1,-1), 4),
            ("ROUNDEDCORNERS", [3]),
        ]))
        rows.append([cell])
        rows.append([Spacer(1, 2)])
    outer = Table(rows, colWidths=[HCW])
    outer.setStyle(TableStyle([
        ("LEFTPADDING",  (0,0), (-1,-1), 0),
        ("RIGHTPADDING", (0,0), (-1,-1), 0),
        ("TOPPADDING",   (0,0), (-1,-1), 0),
        ("BOTTOMPADDING",(0,0), (-1,-1), 0),
    ]))
    return outer

meta_col = algo_box(meta_steps, TEAL)
phy_col  = algo_box(phy_steps,  RED)

algo_label_meta = Table([[Paragraph("METAPHYSEAL PATHWAY", algo_title_style)]], colWidths=[HCW])
algo_label_meta.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), TEAL),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
]))
algo_label_phy = Table([[Paragraph("PHYSEAL PATHWAY", algo_title_style)]], colWidths=[HCW])
algo_label_phy.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), RED),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
]))

algo_outer = Table(
    [[algo_label_meta, Spacer(4*mm, 1), algo_label_phy],
     [meta_col,        Spacer(4*mm, 1), phy_col]],
    colWidths=[HCW, 4*mm, HCW]
)
algo_outer.setStyle(TableStyle([
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("LEFTPADDING",  (0,0), (-1,-1), 0),
    ("RIGHTPADDING", (0,0), (-1,-1), 0),
    ("TOPPADDING",   (0,0), (-1,-1), 0),
    ("BOTTOMPADDING",(0,0), (-1,-1), 0),
]))
story.append(algo_outer)
story.append(sp(6))

# ══════════════════════════════════════════════════════════════════════════════
# ROW 3:  Surgical Options  |  Complications
# ══════════════════════════════════════════════════════════════════════════════
# ── LEFT: Surgical options ────────────────────────────────────────────────────
so_header = section_header("SURGICAL OPTIONS", AMBER, LTAMBER, CW)
so_data = [
    [Paragraph("<b>Technique</b>", SMALLB), Paragraph("<b>Indication</b>", SMALLB)],
    [Paragraph("Percutaneous K-wire\n(transphyseal)", SMALL),
     Paragraph("Unstable metaphyseal complete fractures;\nfirst-line surgical option", SMALL)],
    [Paragraph("Intrafocal K-wire\n(Kapandji)", SMALL),
     Paragraph("Unstable SH II — avoids transphyseal pin;\npreserves growth plate", SMALL)],
    [Paragraph("Elastic intramedullary\nnails (TENS/ESIN)", SMALL),
     Paragraph("Unstable distal shaft / diaphyseal;\nhigher morbidity than K-wires", SMALL)],
    [Paragraph("ORIF (plate/screw)", SMALL),
     Paragraph("SH III/IV intra-articular; irreducible fractures;\nnear-skeletal maturity", SMALL)],
]
so_col_w = [CW*0.40, CW*0.60]
so_table = Table(so_data, colWidths=so_col_w)
so_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), colors.HexColor("#B7850A")),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LTAMBER]),
    ("FONTSIZE", (0,0), (-1,-1), 7),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#CCCCCC")),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))

# ── RIGHT: Complications ──────────────────────────────────────────────────────
cx_header = section_header("COMPLICATIONS", RED, LTRED, CW)
cx_data = [
    [Paragraph("<b>Complication</b>", SMALLB), Paragraph("<b>Key Points</b>", SMALLB)],
    [Paragraph("Redisplacement", SMALL),
     Paragraph("20-35% after cast alone; 0-5% after K-wire;\npeak at 1-2 weeks - mandatory X-ray review", SMALL)],
    [Paragraph("Malunion", SMALL),
     Paragraph("Often tolerated in young children (remodels);\nsignificant in older patients/near-skeletal maturity", SMALL)],
    [Paragraph("Growth disturbance", SMALL),
     Paragraph("Risk correlates with SH grade; also increased\nby delayed reduction (>3 days) or repeat attempts", SMALL)],
    [Paragraph("Nerve injury\n(median/AIN)", SMALL),
     Paragraph("Usually neuropraxia; resolves spontaneously;\nassess motor/sensory at presentation", SMALL)],
    [Paragraph("Compartment\nsyndrome", SMALL),
     Paragraph("Rare but exclude in displaced fractures;\n5 Ps — urgent fasciotomy if suspected", SMALL)],
    [Paragraph("Refracture", SMALL),
     Paragraph("Protective splinting for high-risk activities\nafter cast removal", SMALL)],
]
cx_col_w = [CW*0.32, CW*0.68]
cx_table = Table(cx_data, colWidths=cx_col_w)
cx_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), RED),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LTRED]),
    ("FONTSIZE", (0,0), (-1,-1), 7),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#CCCCCC")),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))

row3 = Table(
    [[so_header, "", cx_header],
     [so_table,  "", cx_table]],
    colWidths=[CW, 4*mm, CW]
)
row3.setStyle(TableStyle([
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("LEFTPADDING",  (0,0), (-1,-1), 0),
    ("RIGHTPADDING", (0,0), (-1,-1), 0),
    ("TOPPADDING",   (0,0), (-1,-1), 0),
    ("BOTTOMPADDING",(0,0), (-1,-1), 2),
]))
story.append(row3)
story.append(sp(6))

# ══════════════════════════════════════════════════════════════════════════════
# SURGICAL REFERRAL INDICATIONS  (full width, red border box)
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("INDICATIONS FOR URGENT ORTHOPAEDIC REFERRAL", RED, LTRED, W))
story.append(sp(2))

referral_items = [
    "Open fracture",
    "Neurovascular compromise (pulseless limb → vascular surgery urgently)",
    "Compartment syndrome",
    "Failed or irreducible closed reduction",
    "Salter-Harris III, IV, or V injuries",
    "Intra-articular fracture",
    "Significantly displaced fractures in skeletally mature adolescents",
    "Suspected child abuse (non-accidental injury) pattern",
]
ref_cols = [referral_items[:4], referral_items[4:]]
ref_left  = "\n".join(f"• {x}" for x in ref_cols[0])
ref_right = "\n".join(f"• {x}" for x in ref_cols[1])

ref_style = ParagraphStyle("Ref", fontName="Helvetica", fontSize=7.5,
                           leading=12, textColor=BLACK)
ref_table = Table(
    [[Paragraph(ref_left, ref_style), Paragraph(ref_right, ref_style)]],
    colWidths=[W*0.5, W*0.5]
)
ref_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), LTRED),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("RIGHTPADDING",  (0,0), (-1,-1), 8),
    ("LINEBELOW", (0,0), (-1,-1), 0.5, RED),
    ("BOX", (0,0), (-1,-1), 1, RED),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(ref_table)
story.append(sp(5))

# ══════════════════════════════════════════════════════════════════════════════
# FOOTER
# ══════════════════════════════════════════════════════════════════════════════
story.append(ColoredHR(W, MIDGREY, 0.5))
story.append(sp(3))
footer_data = [
    [Paragraph("References: Noonan & Price criteria | SICOT-J 2026 systematic review (45 studies, 5,340 pts) | StatPearls Distal Radius Fractures | RCH Melbourne Clinical Guidelines | PMC10364841", FOOTNOTE),
     Paragraph("Orris Medical  |  June 2026\nFor educational use only. Verify against local guidelines.", FOOTNOTE)]
]
footer_table = Table(footer_data, colWidths=[W*0.70, W*0.30])
footer_table.setStyle(TableStyle([
    ("VALIGN",   (0,0), (-1,-1), "TOP"),
    ("ALIGN",    (1,0), (1,0), "RIGHT"),
    ("TOPPADDING",    (0,0), (-1,-1), 0),
    ("BOTTOMPADDING", (0,0), (-1,-1), 0),
    ("LEFTPADDING",   (0,0), (-1,-1), 0),
    ("RIGHTPADDING",  (0,0), (-1,-1), 0),
]))
story.append(footer_table)

# ── BUILD ────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF saved to: {OUTPUT}")
Running Command

cd /home/daytona/workspace/paeds-radius-pdf && python3 build_pdf.py 2>&1

Editing File

~/paeds-radius-pdf/build_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/paeds-radius-pdf/build_pdf.py'
Editing File

~/paeds-radius-pdf/build_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/paeds-radius-pdf/build_pdf.py'
Running Command

cd /home/daytona/workspace/paeds-radius-pdf && python3 build_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/paeds-radius-pdf/Paeds_Distal_Radius_QR.pdf

Running Command

python3 -c " from pypdf import PdfReader r = PdfReader('/home/daytona/workspace/paeds-radius-pdf/Paeds_Distal_Radius_QR.pdf') print(f'Pages: {len(r.pages)}') for i, p in enumerate(r.pages): txt = p.extract_text() print(f'Page {i+1} chars: {len(txt)}') print(txt[:200]) print('---') "

2 pages, all content rendering correctly. Your quick reference PDF is ready:

Paeds Distal Radius QR

PDF Document · PDF


Here's what's packed into the 2-page colour-coded card:
Page 1
  • Fracture Types table - Torus, Greenstick, Complete, Plastic deformation with stability rating
  • Key Paediatric Principles - remodeling, one-attempt rule, bayonet apposition, Galeazzi equivalent
  • Acceptable Reduction Parameters (full-width, colour-coded) - Noonan & Price criteria across 4 age bands: sagittal/coronal angulation, rotation, bayonet apposition
  • Salter-Harris Physeal Guide - all 5 types with frequency, growth disturbance risk, and ED management; HIGH/VERY HIGH risk flagged in red
  • Metaphyseal Fracture Management table - torus through high-risk complete with cast type and duration
Page 2
  • Management Algorithm - dual-column flowchart separating Metaphyseal vs Physeal pathways with colour-coded decision boxes
  • Surgical Options - K-wire (transphyseal vs Kapandji), TENS/ESIN, ORIF with specific indications
  • Complications - redisplacement rates (20-35% cast vs 0-5% K-wire), growth arrest, nerve injury, compartment syndrome
  • Urgent Referral Indications - highlighted red box with 8 criteria
  • Footer with references (SICOT-J 2026, Noonan & Price, RCH guidelines)
This is a shared conversation. Sign in to Orris to start your own chat.