Scalp anatomy in detailed explanation and in simple way
scalp anatomy layers SCALP mnemonic detailed explanation
| Letter | Layer | Simple Meaning |
|---|---|---|
| S | Skin | The outermost layer with hair |
| C | Connective tissue (subcutaneous/superficial fascia) | Fatty, fibrous layer under the skin |
| A | Aponeurosis (galea aponeurotica) | Tough sheet of fibrous tissue |
| L | Loose areolar connective tissue | A "slippery" spacer layer |
| P | Pericranium (periosteum) | Membrane covering the skull bone |


| Artery | Source | Region Supplied |
|---|---|---|
| Supratrochlear & Supraorbital | Ophthalmic artery (from internal carotid) | Frontal scalp |
| Superficial temporal | External carotid | Temporal (side) scalp |
| Posterior auricular | External carotid | Behind the ear |
| Occipital | External carotid | Back of scalp |
All arteries anastomose (connect) freely with each other, so scalp blood supply is exceptionally rich - this allows scalp wounds to bleed a lot, but also means wounds heal well.
| Clinical Layer | Anatomical Content | Key Feature |
|---|---|---|
| Outer layer | Skin + Subcutaneous tissue + Galea | Firmly adherent; moves as one unit |
| Subaponeurotic layer | Loose areolar tissue | "Danger space" - infection/blood spreads here |
| Pericranium | Periosteum | Attached to skull; cannot be sutured |
| Nerve | Origin | Area |
|---|---|---|
| Supratrochlear & Supraorbital | CN V1 (ophthalmic) | Forehead, front scalp |
| Zygomaticotemporal | CN V2 (maxillary) | Temple |
| Auriculotemporal | CN V3 (mandibular) | Temporal/side |
| Lesser & Greater Occipital | C2, C3 cervical | Back of scalp |
| Great Auricular | C2, C3 | Behind the ear |
The scalp has 5 layers (remembered as S-C-A-L-P): Skin (thick, hairy) → Connective tissue (very vascular, bleeds profusely) → Aponeurosis/galea (tough fibrous sheet) → Loose areolar tissue (the "danger space" with emissary veins) → Pericranium (thin membrane on the skull). The outer 3 layers move as one unit; the 4th layer is where infections and blood spread easily to the brain.
Create a visual atlas PDF of scalp anatomy with labeled diagrams
mkdir -p /home/daytona/workspace/scalp-atlas && ls /home/daytona/workspace/scalp-atlas
cd /home/daytona/workspace/scalp-atlas && curl -s -o img_layers.png "https://cdn.orris.care/cdss_images/c0751ecc7bdbf89f87e3b7b1082d5ea2c3517f043050f8d4de09aca95c75494b.png" && curl -s -o img_coronal.png "https://cdn.orris.care/cdss_images/78e61d792696e3900c0b01943b8a41a2ebddc6f56c22aa4e6e7f0011b5e2e87a.png" && ls -lh *.png
~/scalp-atlas/build_atlas.py
"""
Scalp Anatomy Visual Atlas - PDF Generator
Uses reportlab to build a multi-page, richly annotated PDF atlas.
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import cm, mm
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Image, Table, TableStyle,
PageBreak, HRFlowable, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.pdfgen import canvas
from reportlab.lib.colors import HexColor
import os
# ── Paths ─────────────────────────────────────────────────────────────────────
BASE = "/home/daytona/workspace/scalp-atlas"
IMG_LAYERS = os.path.join(BASE, "img_layers.png")
IMG_CORONAL = os.path.join(BASE, "img_coronal.png")
OUT_PDF = os.path.join(BASE, "Scalp_Anatomy_Atlas.pdf")
# ── Color palette ─────────────────────────────────────────────────────────────
C_NAVY = HexColor("#1a2744")
C_TEAL = HexColor("#0d6e7a")
C_GOLD = HexColor("#c9860a")
C_LBLUE = HexColor("#e8f4f8")
C_LGOLD = HexColor("#fdf3e1")
C_LGREEN = HexColor("#e8f5e9")
C_LRED = HexColor("#fce4e4")
C_GREY = HexColor("#f5f5f5")
C_DGREY = HexColor("#444444")
C_WHITE = colors.white
C_BLACK = colors.black
W, H = A4 # 595.27 x 841.89 pts
# ── Page numbering callback ───────────────────────────────────────────────────
page_num = [0]
def on_page(canvas_obj, doc):
page_num[0] += 1
canvas_obj.saveState()
# Footer bar
canvas_obj.setFillColor(C_NAVY)
canvas_obj.rect(0, 0, W, 1.1*cm, fill=1, stroke=0)
canvas_obj.setFillColor(C_WHITE)
canvas_obj.setFont("Helvetica", 8)
canvas_obj.drawCentredString(W/2, 0.38*cm, f"Scalp Anatomy Visual Atlas • Page {page_num[0]}")
canvas_obj.drawString(1.5*cm, 0.38*cm, "© Educational Reference Only")
canvas_obj.drawRightString(W - 1.5*cm, 0.38*cm, "Sources: Roberts & Hedges | Dikshit FMT | Dermatology 5e")
# Header bar (skip page 1 – it has its own cover)
if page_num[0] > 1:
canvas_obj.setFillColor(C_NAVY)
canvas_obj.rect(0, H - 1.1*cm, W, 1.1*cm, fill=1, stroke=0)
canvas_obj.setFillColor(C_WHITE)
canvas_obj.setFont("Helvetica-Bold", 9)
canvas_obj.drawString(1.5*cm, H - 0.72*cm, "SCALP ANATOMY VISUAL ATLAS")
canvas_obj.setFont("Helvetica", 9)
canvas_obj.drawRightString(W - 1.5*cm, H - 0.72*cm, "Anatomy | Clinical Correlates | Mnemonics")
canvas_obj.restoreState()
# ── Style helpers ─────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
base = styles[name]
return ParagraphStyle(name + "_custom", parent=base, **kw)
TITLE_STYLE = S("Title", fontSize=28, textColor=C_WHITE, alignment=TA_CENTER,
spaceAfter=6, fontName="Helvetica-Bold")
SUBTITLE_STYLE= S("Normal", fontSize=13, textColor=HexColor("#afd8e8"),
alignment=TA_CENTER, fontName="Helvetica-Oblique")
H1 = S("Heading1", fontSize=16, textColor=C_NAVY, fontName="Helvetica-Bold",
spaceBefore=10, spaceAfter=4)
H2 = S("Heading2", fontSize=13, textColor=C_TEAL, fontName="Helvetica-Bold",
spaceBefore=8, spaceAfter=3)
H3 = S("Heading3", fontSize=11, textColor=C_GOLD, fontName="Helvetica-Bold",
spaceBefore=6, spaceAfter=2)
BODY = S("Normal", fontSize=9.5, textColor=C_DGREY, leading=14,
alignment=TA_JUSTIFY)
CAPTION = S("Normal", fontSize=8, textColor=C_TEAL, alignment=TA_CENTER,
fontName="Helvetica-Oblique", spaceBefore=3, spaceAfter=6)
SMALL = S("Normal", fontSize=8, textColor=C_DGREY, leading=12)
MNEM = S("Normal", fontSize=12, textColor=C_NAVY, fontName="Helvetica-Bold",
alignment=TA_CENTER)
DANGER = S("Normal", fontSize=9.5, textColor=HexColor("#8b0000"),
fontName="Helvetica-Bold", leading=14)
BULLET = S("Normal", fontSize=9.5, textColor=C_DGREY, leading=14,
leftIndent=14, bulletIndent=4)
# ── Custom Flowables ─────────────────────────────────────────────────────────
class ColorBox(Flowable):
"""A colored rounded rectangle header band."""
def __init__(self, text, bg=C_NAVY, fg=C_WHITE, height=1.1*cm, font_size=14):
Flowable.__init__(self)
self.text = text
self.bg = bg
self.fg = fg
self.height = height
self.font_size = font_size
self.width = W - 3*cm # set in wrap
def wrap(self, availWidth, availHeight):
self.width = availWidth
return (availWidth, self.height)
def draw(self):
c = self.canv
c.setFillColor(self.bg)
c.roundRect(0, 0, self.width, self.height, 6, fill=1, stroke=0)
c.setFillColor(self.fg)
c.setFont("Helvetica-Bold", self.font_size)
c.drawCentredString(self.width/2, self.height/2 - self.font_size/3, self.text)
class HRule(Flowable):
def __init__(self, color=C_TEAL, thickness=1.5):
Flowable.__init__(self)
self.color = color
self.thickness = thickness
def wrap(self, aw, ah):
self.width = aw
return (aw, self.thickness + 2)
def draw(self):
self.canv.setStrokeColor(self.color)
self.canv.setLineWidth(self.thickness)
self.canv.line(0, 1, self.width, 1)
# ── Table helpers ────────────────────────────────────────────────────────────
def styled_table(data, col_widths, header_bg=C_NAVY, alt_bg=C_GREY):
ts = TableStyle([
# Header row
("BACKGROUND", (0,0), (-1,0), header_bg),
("TEXTCOLOR", (0,0), (-1,0), C_WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 9),
("ALIGN", (0,0), (-1,0), "CENTER"),
("BOTTOMPADDING",(0,0),(-1,0), 6),
("TOPPADDING", (0,0), (-1,0), 6),
# Body
("FONTNAME", (0,1), (-1,-1), "Helvetica"),
("FONTSIZE", (0,1), (-1,-1), 8.5),
("TOPPADDING", (0,1), (-1,-1), 5),
("BOTTOMPADDING",(0,1),(-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING",(0,0), (-1,-1), 8),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#cccccc")),
("ROWBACKGROUNDS",(0,1),(-1,-1),[C_WHITE, alt_bg]),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
])
t = Table(data, colWidths=col_widths, repeatRows=1)
t.setStyle(ts)
return t
def highlight_box(text_para_list, bg=C_LBLUE, border=C_TEAL):
"""Wrap content in a colored bordered box via a 1-cell Table."""
ts = TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("LINEAFTER", (0,0), (0,-1), 3, border),
("LINEBEFORE", (0,0), (0,-1), 3, border),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING",(0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 12),
("RIGHTPADDING", (0,0), (-1,-1), 12),
("BOX", (0,0), (-1,-1), 1, border),
])
t = Table([[text_para_list]], colWidths=[W - 3*cm])
t.setStyle(ts)
return t
# ── Build story ───────────────────────────────────────────────────────────────
story = []
# ═══════════════════════════════════════════════════════════════════
# PAGE 1 – COVER
# ═══════════════════════════════════════════════════════════════════
class CoverPage(Flowable):
def wrap(self, aw, ah):
return (aw, ah)
def draw(self):
c = self.canv
# Full navy background
c.setFillColor(C_NAVY)
c.rect(0, 0, W, H, fill=1, stroke=0)
# Decorative teal band top
c.setFillColor(C_TEAL)
c.rect(0, H - 2.5*cm, W, 2.5*cm, fill=1, stroke=0)
# Decorative gold accent line
c.setFillColor(C_GOLD)
c.rect(0, H - 2.7*cm, W, 0.2*cm, fill=1, stroke=0)
# Gold accent line bottom
c.setFillColor(C_GOLD)
c.rect(0, 2.2*cm, W, 0.2*cm, fill=1, stroke=0)
# Title text
c.setFillColor(C_WHITE)
c.setFont("Helvetica-Bold", 32)
c.drawCentredString(W/2, H - 6*cm, "SCALP ANATOMY")
c.setFont("Helvetica-Bold", 22)
c.setFillColor(HexColor("#afd8e8"))
c.drawCentredString(W/2, H - 7.2*cm, "Visual Atlas")
# Subtitle
c.setFillColor(C_GOLD)
c.setFont("Helvetica-Oblique", 13)
c.drawCentredString(W/2, H - 8.4*cm,
"Layers • Vasculature • Nerves • Clinical Correlates")
# Divider
c.setStrokeColor(C_TEAL)
c.setLineWidth(1.5)
c.line(3*cm, H - 9*cm, W - 3*cm, H - 9*cm)
# SCALP mnemonic large display
letters = [("S","Skin"),("C","Connective Tissue"),
("A","Aponeurosis (Galea)"),("L","Loose Areolar Tissue"),("P","Pericranium")]
y = H - 10.2*cm
for letter, meaning in letters:
c.setFillColor(C_GOLD)
c.setFont("Helvetica-Bold", 22)
c.drawString(5.5*cm, y, letter)
c.setFillColor(C_WHITE)
c.setFont("Helvetica", 13)
c.drawString(7*cm, y + 0.1*cm, meaning)
y -= 1.1*cm
# Bottom info bar
c.setFillColor(HexColor("#0d2a3a"))
c.rect(0, 0, W, 2.4*cm, fill=1, stroke=0)
c.setFillColor(HexColor("#afd8e8"))
c.setFont("Helvetica", 9)
c.drawCentredString(W/2, 1.4*cm, "Based on: Roberts & Hedges' Clinical Procedures in Emergency Medicine")
c.drawCentredString(W/2, 0.9*cm, "P C Dikshit Textbook of Forensic Medicine & Toxicology | Dermatology 2-Volume Set 5e")
story.append(CoverPage())
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════
# PAGE 2 – OVERVIEW & BOUNDARIES
# ═══════════════════════════════════════════════════════════════════
story += [
ColorBox("1. SCALP — OVERVIEW & BOUNDARIES", bg=C_NAVY),
Spacer(1, 0.4*cm),
Paragraph(
"The <b>scalp</b> is the multilayered soft-tissue covering of the skull vault. "
"It is one of the most vascular structures in the body, with a rich arterial supply "
"and extensive venous drainage that has direct intracranial connections.",
BODY),
Spacer(1, 0.3*cm),
H2("Anatomical Boundaries"),
]
bounds_data = [
["Direction", "Boundary Landmark"],
["Anteriorly", "Supraorbital ridges (brow ridges)"],
["Posteriorly", "External occipital protuberance (inion)"],
["Laterally", "Zygomatic arch & external acoustic meatus (ear canal)"],
["Superior", "Vertex of the skull"],
]
story.append(styled_table(bounds_data, [5*cm, 11*cm]))
story.append(Spacer(1, 0.4*cm))
story += [
H2("The SCALP Mnemonic"),
Paragraph(
"Each letter of the word <b>SCALP</b> names one of the five anatomical layers "
"from superficial to deep:", BODY),
Spacer(1, 0.25*cm),
]
scalp_data = [
["Layer", "Name", "Key Feature"],
["S", "Skin", "Thickest skin in body; hair follicles, sebaceous & sweat glands"],
["C", "Connective tissue (SQ)", "Dense fibro-fatty; all major vessels & nerves run here"],
["A", "Aponeurosis (Galea)", "Tough fibrous sheet; connects frontalis ↔ occipitalis"],
["L", "Loose areolar tissue", "\"Danger space\" — emissary veins; blood/infection spreads here"],
["P", "Pericranium", "Periosteum of skull; firm at sutures; biologically active"],
]
ts = TableStyle([
("BACKGROUND", (0,0), (-1,0), C_NAVY),
("TEXTCOLOR", (0,0), (-1,0), C_WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 9),
("ALIGN", (0,0), (0,-1), "CENTER"),
("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"),
("FONTSIZE", (0,1), (0,-1), 18),
("TEXTCOLOR", (0,1), (0,-1), C_GOLD),
("FONTNAME", (1,1), (-1,-1),"Helvetica"),
("FONTSIZE", (1,1), (-1,-1), 8.5),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING",(0,0),(-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING",(0,0), (-1,-1), 8),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#cccccc")),
("ROWBACKGROUNDS",(0,1),(-1,-1),[C_WHITE, C_GREY]),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
])
t = Table(scalp_data, colWidths=[1.5*cm, 4.5*cm, 10*cm], repeatRows=1)
t.setStyle(ts)
story.append(t)
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════
# PAGE 3 – LAYER CROSS-SECTION DIAGRAM
# ═══════════════════════════════════════════════════════════════════
story += [
ColorBox("2. LAYERS — CROSS-SECTION DIAGRAMS", bg=C_TEAL),
Spacer(1, 0.3*cm),
H2("Figure A: 3-D Exploded Cross-Section of Scalp Layers"),
Paragraph(
"The diagram below shows all five layers with their spatial relationships, "
"the emissary vein passing through the subaponeurotic space, and the "
"venous sinus beneath the skull.", BODY),
Spacer(1, 0.3*cm),
Image(IMG_LAYERS, width=14.5*cm, height=10.5*cm, hAlign="CENTER"),
Paragraph(
"Figure A. Cross-section of scalp layers. Note the outer layer (Skin + SQ fascia + Galea) "
"is surgically considered as one unit. The emissary vein runs through the loose areolar "
"tissue into the skull and connects to the intracranial venous sinus.\n"
"Source: Roberts and Hedges' Clinical Procedures in Emergency Medicine", CAPTION),
Spacer(1, 0.5*cm),
HRule(),
Spacer(1, 0.4*cm),
H2("Figure B: Coronal Section — Scalp to Brain"),
Paragraph(
"This deeper view shows the full relationship from scalp skin down to the cerebral cortex, "
"including the meningeal layers, venous connections, and intracranial structures.", BODY),
Spacer(1, 0.3*cm),
Image(IMG_CORONAL, width=14.5*cm, height=10*cm, hAlign="CENTER"),
Paragraph(
"Figure B. Coronal section through scalp, skull and brain. Shows emissary vein, "
"diploic vein, pericranium, parietal bone, dura mater, arachnoid mater, pia mater, "
"falx cerebri, and superior sagittal sinus.\n"
"Source: P C Dikshit Textbook of Forensic Medicine and Toxicology", CAPTION),
]
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════
# PAGE 4 – LAYER-BY-LAYER DETAIL
# ═══════════════════════════════════════════════════════════════════
story += [
ColorBox("3. LAYER-BY-LAYER ANATOMY", bg=C_NAVY),
Spacer(1, 0.4*cm),
]
layers_detail = [
{
"letter": "S",
"title": "Layer 1 — SKIN",
"bg": C_LGOLD,
"border": C_GOLD,
"points": [
"<b>Thickest skin</b> anywhere in the body.",
"Contains abundant <b>hair follicles, sebaceous glands</b> (sebum production), and <b>eccrine sweat glands</b>.",
"Tightly bound to the SQ fascia below by vertical fibrous septa.",
"The septa <b>prevent vessel retraction</b> when cut — this is why scalp wounds bleed profusely.",
"Resists tearing; provides protection against minor trauma.",
]
},
{
"letter": "C",
"title": "Layer 2 — CONNECTIVE TISSUE (Subcutaneous Fascia)",
"bg": C_LBLUE,
"border": C_TEAL,
"points": [
"A <b>dense fibro-fatty layer</b> firmly attached to skin above and galea below.",
"<b>Main source of bleeding</b> in scalp wounds — vessels cannot retract due to surrounding fibrous stroma.",
"Contains all major scalp <b>arteries, veins, lymphatics, and sensory nerves</b>.",
"Arteries anastomose freely, giving the scalp exceptional blood supply and wound-healing capacity.",
"Clinically: direct pressure and rapid wound closure (not vessel ligation alone) controls bleeding.",
]
},
{
"letter": "A",
"title": "Layer 3 — APONEUROSIS (Galea Aponeurotica)",
"bg": C_LGREEN,
"border": HexColor("#388e3c"),
"points": [
"A tough, flat <b>fibromuscular sheet</b> (epicranial aponeurosis).",
"Connects <b>frontalis muscle</b> (front) to <b>occipitalis muscle</b> (back) = occipitofrontalis muscle.",
"Fused with skin + SQ fascia above — the three move as one <b>'outer scalp unit'</b>.",
"Laterally blends with <b>temporalis fascia</b> over the temples.",
"<b>If a wound gapes open</b>, the galea has been transected — must be sutured separately.",
"The galea also limits spread of infection and hematoma within the outer layer.",
]
},
{
"letter": "L",
"title": "Layer 4 — LOOSE AREOLAR TISSUE (Subaponeurotic Space)",
"bg": C_LRED,
"border": HexColor("#c62828"),
"points": [
"Also called the <b>'Danger Space'</b> of the scalp.",
"Allows the outer scalp (S+C+A) to <b>glide freely</b> over the skull — enables eyebrow raising.",
"Contains <b>emissary veins</b> (valveless) connecting scalp veins → diploic veins → intracranial sinuses.",
"<b>Blood collects here freely</b> (subgaleal hematoma) — can spread across the entire scalp.",
"<b>Infection spreads here</b> → emissary veins → skull osteomyelitis, meningitis, brain abscess.",
"In newborns: subgaleal hematoma (in this layer) crosses suture lines and can be life-threatening.",
]
},
{
"letter": "P",
"title": "Layer 5 — PERICRANIUM (Periosteum of Skull)",
"bg": C_GREY,
"border": C_DGREY,
"points": [
"The <b>periosteum of the outer skull</b> — thin but biologically active.",
"Firmly attached to skull especially at <b>suture lines</b> (this limits cephalohematoma spread in newborns).",
"Contains <b>osteoblasts and osteoclasts</b> — participates in bone repair.",
"Too thin and delicate to hold sutures — not routinely closed in scalp repair.",
"Separates the scalp from the skull bone; rarely disrupted except in severe injuries.",
]
},
]
for layer in layers_detail:
paras = [Paragraph(f"<b>{layer['letter']}</b> {layer['title']}", H2)]
for pt in layer["points"]:
paras.append(Paragraph(f"• {pt}", BULLET))
box = highlight_box(paras, bg=layer["bg"], border=layer["border"])
story.append(box)
story.append(Spacer(1, 0.3*cm))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════
# PAGE 5 – BLOOD SUPPLY
# ═══════════════════════════════════════════════════════════════════
story += [
ColorBox("4. BLOOD SUPPLY OF THE SCALP", bg=C_TEAL),
Spacer(1, 0.4*cm),
Paragraph(
"The scalp has one of the richest blood supplies in the body. <b>Five paired arteries</b> "
"supply the scalp — two from the internal carotid system and three from the external carotid "
"system. They run in the <b>subcutaneous (C) layer</b> and anastomose freely with each other, "
"creating a complete vascular ring around the scalp.",
BODY),
Spacer(1, 0.3*cm),
H2("Arterial Supply"),
]
artery_data = [
["Artery", "Parent Vessel", "System", "Region Supplied"],
["Supratrochlear", "Ophthalmic a. (from ICA)", "Internal carotid", "Medial forehead / front scalp"],
["Supraorbital", "Ophthalmic a. (from ICA)", "Internal carotid", "Lateral forehead / front scalp"],
["Superficial temporal", "External carotid a.", "External carotid", "Temporal / parietal scalp"],
["Posterior auricular", "External carotid a.", "External carotid", "Scalp behind ear"],
["Occipital", "External carotid a.", "External carotid", "Posterior scalp / occiput"],
]
story.append(styled_table(artery_data, [4.5*cm, 4.5*cm, 3.5*cm, 5.5*cm], header_bg=HexColor("#8b0000")))
story.append(Spacer(1, 0.3*cm))
# Key clinical note
note_content = [
Paragraph("<b>⚠ Why scalp wounds bleed so profusely:</b>", DANGER),
Paragraph(
"The fibrous septa of the subcutaneous layer tether arteries to surrounding connective "
"tissue. When a vessel is cut, it <b>cannot retract or constrict</b> normally. Combined with "
"the rich anastomotic network, even small lacerations can cause alarming blood loss. "
"Management: direct compression + rapid suturing (not vessel ligation).",
SMALL),
]
story.append(highlight_box(note_content, bg=C_LRED, border=HexColor("#c62828")))
story.append(Spacer(1, 0.4*cm))
story += [
H2("Venous Drainage"),
Paragraph(
"Venous drainage parallels the arteries, with additional important connections:", BODY),
Spacer(1, 0.2*cm),
]
vein_data = [
["Vein / Vessel", "Drains To", "Clinical Significance"],
["Superficial scalp veins", "External jugular vein", "Primary drainage pathway"],
["Emissary veins", "Diploic veins of skull", "Valveless — can carry infection intracranially"],
["Diploic veins", "Intracranial venous sinuses", "Bridge between scalp and dural sinuses"],
["Superior sagittal sinus", "Confluence of sinuses", "Risk target if scalp infection untreated"],
]
story.append(styled_table(vein_data, [4.5*cm, 5*cm, 7.5*cm], header_bg=C_NAVY))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════
# PAGE 6 – NERVE SUPPLY
# ═══════════════════════════════════════════════════════════════════
story += [
ColorBox("5. NERVE SUPPLY OF THE SCALP", bg=C_NAVY),
Spacer(1, 0.4*cm),
Paragraph(
"The scalp receives sensory innervation from two sources: "
"<b>branches of the trigeminal nerve (CN V)</b> for the anterior scalp, "
"and <b>cervical spinal nerves (C2–C3)</b> for the posterior scalp. "
"Motor supply to the occipitofrontalis muscle comes from the <b>facial nerve (CN VII)</b>.",
BODY),
Spacer(1, 0.3*cm),
H2("Sensory Innervation Map"),
]
nerve_data = [
["Nerve", "Origin", "CN / Level", "Area of Scalp"],
["Supratrochlear n.", "Frontal branch of CN V1 (ophthalmic)", "CN V1", "Medial forehead, frontal scalp"],
["Supraorbital n.", "Frontal branch of CN V1", "CN V1", "Lateral forehead, anterior vertex"],
["Zygomaticotemporal n.","Zygomatic branch of CN V2 (maxillary)","CN V2", "Temple region"],
["Auriculotemporal n.", "Posterior branch of CN V3 (mandibular)","CN V3", "Lateral scalp, temporal region"],
["Lesser occipital n.", "Cervical plexus (C2)", "C2", "Lateral occipital scalp / behind ear"],
["Greater occipital n.","Dorsal ramus of C2", "C2", "Posterior scalp (main supply)"],
["Third occipital n.", "Dorsal ramus of C3", "C3", "Inferior posterior scalp"],
["Great auricular n.", "Cervical plexus (C2–C3)", "C2–C3", "Scalp over parotid, behind auricle"],
]
story.append(styled_table(nerve_data, [3.5*cm, 4.5*cm, 1.8*cm, 6.2*cm], header_bg=C_TEAL))
story.append(Spacer(1, 0.3*cm))
story += [
H2("Motor Supply"),
Paragraph(
"The <b>facial nerve (CN VII)</b> provides motor supply to the frontalis and occipitalis muscles "
"via its temporal and posterior auricular branches respectively. Damage to the temporal branch "
"of the facial nerve causes inability to raise the ipsilateral eyebrow.",
BODY),
Spacer(1, 0.3*cm),
H2("Watershed Zone"),
Paragraph(
"The scalp has a sensory watershed at approximately the <b>vertex</b> — where trigeminal "
"territory (anterior) meets occipital nerve territory (posterior). This line corresponds "
"roughly to a coronal plane through the top of the head.",
BODY),
Spacer(1, 0.3*cm),
]
anesthesia_content = [
Paragraph("<b>🔵 Ring Block for Scalp Anesthesia:</b>", H3),
Paragraph(
"To anesthetize the entire scalp, a circumferential 'ring block' is performed by injecting "
"local anesthetic along the entire hairline, targeting all five nerve pairs listed above. "
"This is used for scalp surgery, lesion excisions, and laceration repair.",
SMALL),
]
story.append(highlight_box(anesthesia_content, bg=C_LBLUE, border=C_TEAL))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════
# PAGE 7 – LYMPHATIC DRAINAGE + MUSCLES
# ═══════════════════════════════════════════════════════════════════
story += [
ColorBox("6. LYMPHATIC DRAINAGE & MUSCLES OF THE SCALP", bg=C_TEAL),
Spacer(1, 0.4*cm),
H2("Lymphatic Drainage"),
Paragraph(
"Scalp lymphatics drain to regional lymph node groups depending on the zone of scalp:", BODY),
Spacer(1, 0.2*cm),
]
lymph_data = [
["Scalp Region", "Drains To", "Node Location"],
["Frontal / anterior", "Pre-auricular (parotid) nodes", "In front of the ear (tragus)"],
["Temporal / parietal", "Pre-auricular & parotid nodes", "In front of ear / parotid gland"],
["Parieto-occipital", "Post-auricular (mastoid) nodes", "Behind the ear (mastoid process)"],
["Occipital", "Occipital nodes", "Base of skull posteriorly"],
["All regions →", "Deep cervical chain", "Along internal jugular vein"],
]
story.append(styled_table(lymph_data, [4.5*cm, 5*cm, 7.5*cm], header_bg=C_NAVY))
story.append(Spacer(1, 0.5*cm))
story += [
H2("Muscles of the Scalp — Occipitofrontalis"),
Paragraph(
"The <b>occipitofrontalis (epicranius)</b> is the primary scalp muscle. It has two bellies "
"connected by the galea aponeurotica:", BODY),
Spacer(1, 0.2*cm),
]
muscle_data = [
["Belly", "Origin", "Insertion", "Action", "Nerve"],
["Frontalis\n(anterior belly)", "Galea aponeurotica", "Skin of forehead + eyebrows", "Raises eyebrows;\nwrinkles forehead", "Temporal branch\nof CN VII"],
["Occipitalis\n(posterior belly)","Occipital bone\n(superior nuchal line)","Galea aponeurotica","Pulls scalp posteriorly;\nanchors galea","Posterior auricular\nbranch of CN VII"],
]
ts2 = TableStyle([
("BACKGROUND", (0,0), (-1,0), C_NAVY),
("TEXTCOLOR", (0,0), (-1,0), C_WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 9),
("FONTNAME", (0,1), (-1,-1),"Helvetica"),
("FONTSIZE", (0,1), (-1,-1), 8.5),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING",(0,0),(-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 7),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#cccccc")),
("ROWBACKGROUNDS",(0,1),(-1,-1),[C_WHITE, C_GREY]),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
])
t2 = Table(muscle_data, colWidths=[3*cm, 3.5*cm, 3.5*cm, 3.5*cm, 3.5*cm], repeatRows=1)
t2.setStyle(ts2)
story.append(t2)
story.append(Spacer(1, 0.3*cm))
story += [
H2("Temporoparietal Fascia (TPF)"),
Paragraph(
"Lateral to the galea, the scalp fascia transitions into the <b>temporoparietal fascia (TPF)</b>. "
"The TPF lies just under the subcutaneous tissue of the lateral scalp and is continuous with "
"the galea. It is a key surgical flap donor site in reconstructive surgery. "
"It is supplied by the superficial temporal artery.", BODY),
]
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════
# PAGE 8 – CLINICAL CORRELATES
# ═══════════════════════════════════════════════════════════════════
story += [
ColorBox("7. CLINICAL CORRELATES", bg=C_NAVY),
Spacer(1, 0.4*cm),
]
clinical = [
{
"title": "Scalp Lacerations",
"bg": C_LRED, "border": HexColor("#c62828"),
"text": (
"Scalp lacerations bleed profusely because vessels in the SQ fascia (Layer C) cannot retract. "
"Wounds that <b>gape open</b> indicate galea transection — the galea must be sutured separately "
"to restore integrity and prevent infection spreading to Layer L. <b>Stellate lacerations</b> are "
"common because the inelastic SQ fascia anchors the skin tightly, causing it to split radially "
"under blunt force."
)
},
{
"title": "Subgaleal Hematoma (Subaponeurotic Hematoma)",
"bg": C_LBLUE, "border": C_TEAL,
"text": (
"Blood collects in Layer L (loose areolar tissue) between the galea and pericranium. "
"Because this layer has <b>no fascial barriers</b>, blood can spread over the entire calvarium. "
"In neonates, subgaleal hematoma is a <b>life-threatening emergency</b> — can hold up to "
"260 mL blood (the entire neonate blood volume). Crosses suture lines (unlike cephalohematoma)."
)
},
{
"title": "Cephalohematoma (Neonates)",
"bg": C_LGOLD, "border": C_GOLD,
"text": (
"A subperiosteal hematoma beneath the pericranium (Layer P). Because the pericranium is "
"attached at <b>suture lines</b>, the hematoma is limited to a single skull bone — it does "
"<b>not cross</b> suture lines. Contrast with subgaleal hematoma which does cross sutures."
)
},
{
"title": "Danger Space Infections",
"bg": C_LRED, "border": HexColor("#c62828"),
"text": (
"Layer L contains <b>valveless emissary veins</b> connecting scalp to intracranial sinuses. "
"Untreated infection in this layer can spread via emissary veins causing: "
"<b>osteomyelitis</b> of the skull, <b>meningitis</b>, intracranial <b>venous sinus thrombosis</b>, "
"or <b>brain abscess</b>. Galeal laceration closure is protective."
)
},
{
"title": "Scalp Avulsion",
"bg": C_LGOLD, "border": C_GOLD,
"text": (
"The looseness of Layer L allows the entire outer scalp (S+C+A) to be avulsed (torn away) from "
"the skull in one sheet — a degloving injury. This can occur when hair becomes caught in "
"machinery, or from traction forces during road traffic accidents. The scalp may even be "
"completely separated from the skull."
)
},
{
"title": "Scalp Contusion — Wandering Bruise",
"bg": C_LBLUE, "border": C_TEAL,
"text": (
"Blood from a scalp contusion cannot spread downward (blocked by the rigid skull and "
"pericranium). Instead it spreads laterally in the loose Layer L. A <b>frontal contusion</b> "
"may migrate downward to appear as a periorbital 'black eye'. A <b>temporal contusion</b> "
"may later appear behind the ear — misleading examiners about the site of injury."
)
},
]
for item in clinical:
content = [
Paragraph(f"<b>{item['title']}</b>", H3),
Paragraph(item["text"], SMALL),
]
story.append(highlight_box(content, bg=item["bg"], border=item["border"]))
story.append(Spacer(1, 0.25*cm))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════
# PAGE 9 – SUMMARY QUICK-REFERENCE TABLE + MNEMONICS
# ═══════════════════════════════════════════════════════════════════
story += [
ColorBox("8. QUICK-REFERENCE SUMMARY", bg=C_TEAL),
Spacer(1, 0.4*cm),
H2("Master Summary Table"),
]
summary_data = [
["Layer", "Name", "Contents", "Clinical Note"],
["S (1)", "Skin",
"Hair follicles, sebaceous glands, sweat glands, epidermis + dermis",
"Thickest skin; tightly anchored; resistant to tearing"],
["C (2)", "Subcutaneous\nConnective Tissue",
"Arteries, veins, lymphatics, sensory nerves, fibrous septa",
"Source of profuse bleeding; vessels cannot retract"],
["A (3)", "Aponeurosis\n(Galea)",
"Fibromuscular sheet; connects frontalis & occipitalis",
"Wound gaping = galea cut; must be sutured; limits infection"],
["L (4)", "Loose Areolar\nTissue",
"Emissary veins, lymphatics, loose connective tissue",
"DANGER SPACE — infection/blood spreads intracranially"],
["P (5)", "Pericranium",
"Periosteum; osteoblasts and osteoclasts",
"Attached at sutures; limits cephalohematoma; too thin to suture"],
]
ts3 = TableStyle([
("BACKGROUND", (0,0), (-1,0), C_NAVY),
("TEXTCOLOR", (0,0), (-1,0), C_WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 9),
("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"),
("TEXTCOLOR", (0,1), (0,-1), C_GOLD),
("FONTSIZE", (0,1), (0,-1), 11),
("FONTNAME", (1,1), (-1,-1),"Helvetica"),
("FONTSIZE", (1,1), (-1,-1), 8),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING",(0,0),(-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 7),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#cccccc")),
("ROWBACKGROUNDS",(0,1),(-1,-1),[C_WHITE, C_GREY]),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
# Color-code danger space
("BACKGROUND", (0,4), (-1,4), C_LRED),
])
t3 = Table(summary_data, colWidths=[1.5*cm, 3.5*cm, 6*cm, 6*cm], repeatRows=1)
t3.setStyle(ts3)
story.append(t3)
story.append(Spacer(1, 0.5*cm))
story += [
H2("Memory Aids"),
Spacer(1, 0.2*cm),
]
# Mnemonic card
mnem_data = [
[Paragraph("<b>S</b>", ParagraphStyle("M", fontName="Helvetica-Bold", fontSize=22, textColor=C_GOLD, alignment=TA_CENTER)),
Paragraph("<b>Skin</b> — Some", ParagraphStyle("Mb", fontName="Helvetica-Bold", fontSize=11, textColor=C_NAVY))],
[Paragraph("<b>C</b>", ParagraphStyle("M", fontName="Helvetica-Bold", fontSize=22, textColor=C_GOLD, alignment=TA_CENTER)),
Paragraph("<b>Connective tissue</b> — Clever", ParagraphStyle("Mb", fontName="Helvetica-Bold", fontSize=11, textColor=C_NAVY))],
[Paragraph("<b>A</b>", ParagraphStyle("M", fontName="Helvetica-Bold", fontSize=22, textColor=C_GOLD, alignment=TA_CENTER)),
Paragraph("<b>Aponeurosis</b> — Anatomists", ParagraphStyle("Mb", fontName="Helvetica-Bold", fontSize=11, textColor=C_NAVY))],
[Paragraph("<b>L</b>", ParagraphStyle("M", fontName="Helvetica-Bold", fontSize=22, textColor=C_GOLD, alignment=TA_CENTER)),
Paragraph("<b>Loose areolar tissue</b> — Love", ParagraphStyle("Mb", fontName="Helvetica-Bold", fontSize=11, textColor=C_NAVY))],
[Paragraph("<b>P</b>", ParagraphStyle("M", fontName="Helvetica-Bold", fontSize=22, textColor=C_GOLD, alignment=TA_CENTER)),
Paragraph("<b>Pericranium</b> — Pizza", ParagraphStyle("Mb", fontName="Helvetica-Bold", fontSize=11, textColor=C_NAVY))],
]
ts_mnem = TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_LGOLD),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0),(-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 15),
("BOX", (0,0), (-1,-1), 1.5, C_GOLD),
("INNERGRID", (0,0), (-1,-1), 0.3, HexColor("#e0c060")),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
])
t_mnem = Table(mnem_data, colWidths=[2.5*cm, 14.5*cm])
t_mnem.setStyle(ts_mnem)
story.append(highlight_box(
[Paragraph("<b>Mnemonic: SCALP</b> (the word itself!) — also remembered as:", H3),
Spacer(1, 0.2*cm),
t_mnem,
Spacer(1, 0.2*cm),
Paragraph('"<i>Some Clever Anatomists Love Pizza</i>"', CAPTION)],
bg=C_LGOLD, border=C_GOLD
))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════
# PAGE 10 – COMPARISON TABLES (Cephalo vs Subgaleal; Clinical 3-layers)
# ═══════════════════════════════════════════════════════════════════
story += [
ColorBox("9. KEY COMPARISONS & CLINICAL LAYERS", bg=C_NAVY),
Spacer(1, 0.4*cm),
H2("Cephalohematoma vs Subgaleal Hematoma vs Caput Succedaneum"),
Paragraph(
"These three neonatal scalp swellings are commonly confused. The anatomical layer "
"determines the clinical behavior of each.", BODY),
Spacer(1, 0.2*cm),
]
compare_data = [
["Feature", "Caput Succedaneum", "Subgaleal Hematoma", "Cephalohematoma"],
["Layer", "Above galea\n(SQ tissue, Layer C)", "Below galea\n(Layer L — Loose areolar)", "Below pericranium\n(Layer P — subperiosteal)"],
["Crosses sutures?", "YES", "YES (dangerous)", "NO (limited to 1 bone)"],
["Onset", "Present at birth", "Hours after birth", "Hours to days after birth"],
["Feel", "Pitting edema", "Fluctuant, firm", "Fluctuant, firm"],
["Size", "Limited", "Can be very large\n(entire calvarium)", "Limited to 1 bone area"],
["Blood?", "No (serum/edema)", "YES — significant hemorrhage", "YES — but limited"],
["Dangerous?", "No", "YES — can cause shock\nand anemia in neonates", "Usually no"],
["Treatment", "Resolves spontaneously", "Monitor; transfuse if needed", "Resolves in weeks; do not aspirate"],
]
ts4 = TableStyle([
("BACKGROUND", (0,0), (-1,0), C_NAVY),
("TEXTCOLOR", (0,0), (-1,0), C_WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 8.5),
("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0),(-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#cccccc")),
("ROWBACKGROUNDS",(0,1),(-1,-1),[C_WHITE, C_GREY]),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("BACKGROUND", (2,1), (2,-1), HexColor("#ffeaea")), # highlight subgaleal column
("TEXTCOLOR", (2,6), (2,7), HexColor("#8b0000")),
])
t4 = Table(compare_data, colWidths=[3.5*cm, 4.5*cm, 4.5*cm, 5*cm], repeatRows=1)
t4.setStyle(ts4)
story.append(t4)
story.append(Spacer(1, 0.5*cm))
story += [
H2("Surgical (Clinical) 3-Layer Division of Scalp"),
Paragraph(
"Surgeons often simplify the scalp into 3 operational layers:", BODY),
Spacer(1, 0.2*cm),
]
surgical_data = [
["Surgical Layer", "Anatomical Layers Included", "Key Property"],
["Outer layer", "Skin (S) + SQ tissue (C) + Galea (A)", "Firmly fused; moves as one unit; if cut, wound gapes"],
["Subaponeurotic layer", "Loose areolar tissue (L)", "Danger space; easily dissected; spreads blood/infection"],
["Pericranium", "Periosteum (P)", "Attached to skull at sutures; too fragile to suture"],
]
story.append(styled_table(surgical_data, [4*cm, 6.5*cm, 7*cm], header_bg=C_TEAL))
story.append(Spacer(1, 0.4*cm))
final_box = [
Paragraph("<b>One-Sentence Summary</b>", H2),
Paragraph(
"The scalp has <b>5 layers (SCALP)</b>: thick <b>S</b>kin anchored to <b>C</b>onnective "
"tissue (where all vessels run and profuse bleeding originates), a tough <b>A</b>poneurosis "
"(galea) connecting the forehead and occipital muscles, a <b>L</b>oose areolar 'danger space' "
"(where blood and infection spread to the brain via emissary veins), and the thin "
"<b>P</b>ericranium over the skull bone.",
BODY),
]
story.append(highlight_box(final_box, bg=C_LBLUE, border=C_TEAL))
# ── Build PDF ─────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUT_PDF,
pagesize=A4,
leftMargin=1.5*cm,
rightMargin=1.5*cm,
topMargin=1.8*cm,
bottomMargin=1.8*cm,
title="Scalp Anatomy Visual Atlas",
author="Orris Medical Reference",
subject="Scalp Anatomy — Layers, Vasculature, Nerves, Clinical Correlates",
)
doc.build(story, onFirstPage=on_page, onLaterPages=on_page)
print(f"PDF saved to: {OUT_PDF}")
cd /home/daytona/workspace/scalp-atlas && python build_atlas.py 2>&1
cd /home/daytona/workspace/scalp-atlas && python -c " import re with open('build_atlas.py', 'r') as f: code = f.read() # Replace standalone H1(\"...\"), H2(\"...\"), H3(\"...\") calls with Paragraph(\"...\", Hx) # Pattern: H1(\"text\") -> Paragraph(\"text\", H1) for hx in ['H1', 'H2', 'H3']: # Match: H2(\"...\") or H2('...') pattern = rf'{hx}\((\"[^\"]*\"|\'[^\']*\')\)' repl = rf'Paragraph(\1, {hx})' code = re.sub(pattern, repl, code) with open('build_atlas.py', 'w') as f: f.write(code) print('Done') "
cd /home/daytona/workspace/scalp-atlas && python build_atlas.py 2>&1
ls -lh /home/daytona/workspace/scalp-atlas/Scalp_Anatomy_Atlas.pdf
Scalp Anatomy Atlas
PDF Document · PDF
| Page | Content |
|---|---|
| 1 - Cover | Full navy/teal/gold design with the SCALP mnemonic displayed prominently |
| 2 - Overview & Boundaries | Anatomical limits table + full SCALP layer summary table with gold letter highlights |
| 3 - Cross-Section Diagrams | Both textbook images (3-D exploded layer view + full coronal section to brain), fully captioned |
| 4 - Layer-by-Layer Detail | Color-coded box per layer (gold=Skin, blue=Connective, green=Galea, red=Danger Space, grey=Pericranium) with clinical bullet points |
| 5 - Blood Supply | Complete arterial table (ICA vs ECA sources) + venous drainage with emissary vein pathway + clinical warning box on bleeding |
| 6 - Nerve Supply | Full sensory nerve table (CN V branches + C2-C3), motor supply, watershed zone, ring block technique |
| 7 - Lymphatics & Muscles | Drainage zones table, occipitofrontalis muscle (both bellies), temporoparietal fascia |
| 8 - Clinical Correlates | 6 color-coded clinical boxes: lacerations, subgaleal hematoma, cephalohematoma, danger space infections, avulsion, wandering bruise |
| 9 - Quick Reference | Master summary table + "Some Clever Anatomists Love Pizza" mnemonic card |
| 10 - Key Comparisons | Caput vs Subgaleal hematoma vs Cephalohematoma 3-way comparison table + surgical 3-layer division |