Can you make a detailed notes on cutaneous hyperandrogenism , etiology, pathogenesis, approach, clinical features, management for university theory md dermatology examination

Reading File
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Finding Sources
Reading File
Reading File
Reading File
Finding Sources
Loading Image
Reading File
I now have all the core content needed from the textbooks. I have enough comprehensive material to write detailed MD exam notes on cutaneous hyperandrogenism. Let me compile the full answer now.

CUTANEOUS HYPERANDROGENISM

Detailed Notes for MD Dermatology University Theory Examination


DEFINITION

Cutaneous hyperandrogenism refers to the clinical manifestations in the skin, hair, and sebaceous glands resulting from excessive androgen activity - either due to elevated circulating androgens or increased end-organ sensitivity to normal androgen levels. The major cutaneous manifestations are:
  • Acne vulgaris (hormonal)
  • Hirsutism
  • Seborrhoea
  • Androgenetic alopecia (AGA)
  • Acanthosis nigricans (as a marker of associated insulin resistance)
The constellation of Seborrhoea, Acne, Hirsutism, and Androgenetic alopecia is termed SAHA syndrome.

ETIOLOGY

A. Ovarian Causes

ConditionNotes
Polycystic Ovarian Syndrome (PCOS)Most common cause; biochemical or clinical hyperandrogenism + chronic anovulation (<9 periods/year) without adrenal or pituitary disease
Functional ovarian hyperandrogenismOvarian steroidogenic dysregulation
Ovarian neoplasmsSertoli-Leydig cell tumors, granulosa-theca cell tumors, hilus cell tumors - low metastatic potential, surgical treatment
HyperthecosisHyperplasia of theca interna cells
Syndromes of extreme insulin resistanceSevere acanthosis nigricans

B. Adrenal Causes

ConditionNotes
Non-classic (late-onset) Congenital Adrenal Hyperplasia (NCAH)Most commonly 21-hydroxylase deficiency (CYP21A2 mutation); elevated 17-OHP is hallmark
Cushing syndromeACTH-driven adrenal androgen excess
Adrenal adenomaSecretes testosterone
Adrenal carcinomaSecretes testosterone + DHEA-S + cortisol
Premature adrenarche
Functional adrenal hyperandrogenism

C. Mixed / Other

ConditionNotes
Idiopathic hyperandrogenismElevated androgens without identifiable cause
Idiopathic hirsutism5-15% of cases; normal androgens, regular cycles - increased end-organ sensitivity
HyperprolactinaemiaProlactinoma, drugs, hypothyroidism; hirsutism + galactorrhoea
AcromegalyElevated GH and IGF-1
HypothyroidismReduces SHBG; increases free androgens
HAIR-AN syndromeHyperandrogenism, Insulin Resistance, Acanthosis Nigricans
PregnancyLuteoma, hyperreactio luteinalis, aromatase deficiency

D. Drug-Induced Causes

  • Exogenous androgens / anabolic steroids
  • Synthetic progestins (norgestrel, norethindrone, norgestimate, desogestrel) - reduce SHBG
  • Danazol, valproate, minoxidil

PATHOGENESIS

Androgen Physiology in Skin

Sources of androgens in women:
  • Ovaries (testosterone, androstenedione)
  • Adrenal cortex (DHEA, DHEA-S, androstenedione)
  • Peripheral conversion (in skin, fat)
Key hormones involved:
  1. Testosterone - the principal circulating androgen
  2. DHT (5α-dihydrotestosterone) - the most potent intracellular androgen; has greater receptor binding affinity
  3. DHEA / DHEA-S - adrenal androgens; weaker but present in large quantities
  4. Androstenedione - intermediate; converted to testosterone peripherally
Key enzyme - 5α-reductase:
  • Converts testosterone → DHT within target tissues (sebaceous glands, hair follicles, genital skin)
  • Two isoforms: Type 1 (sebaceous glands, liver) and Type 2 (hair follicles, genital skin, prostate)
Sex Hormone-Binding Globulin (SHBG):
  • Binds both testosterone and estrogen; only free (unbound) fraction is biologically active
  • SHBG is decreased by: synthetic progestins, obesity, acromegaly, hypothyroidism, insulin resistance → increasing free androgen levels
  • This explains why androgenic findings can appear even with normal total testosterone
Androgen receptor distribution in skin:
  • Androgen receptors are present throughout the skin: sebaceous glands, hair follicles (site-specific), dermal fibroblasts, keratinocytes
  • Androgens also regulate wound healing, epidermal differentiation, and dermal fibroblast function

Mechanisms of Cutaneous Effects

1. Seborrhoea:
  • Androgens (especially DHT) are the primary stimulants of sebaceous gland development and sebum production
  • Androgen receptors are densely expressed in sebaceous glands
  • Increased sebum → altered follicular microenvironment → promotes acne
2. Acne:
  • Androgens stimulate sebaceous gland hypertrophy → excess sebum
  • Altered keratinisation of the follicular infundibulum → microcomedone formation
  • Sebum provides substrate for Cutibacterium acnes → inflammation
  • Pathogenic sequence: androgen excess → ↑ sebum + ↓ linoleic acid → follicular hyperkeratosis → comedone → papule/pustule/nodule
3. Hirsutism:
  • Androgens (primarily DHT) activate androgen receptors in the hair follicle papilla
  • Convert vellus hair (short, fine, unpigmented) → terminal hair (long, pigmented, thick)
  • Transformation occurs in androgen-sensitive areas: upper lip, chin, beard, chest, upper back, lower abdomen
  • The hair growth cycle (anagen-catagen-telogen) is hormonally regulated in a site-specific pattern
4. Androgenetic Alopecia (AGA):
  • Paradoxically, the same DHT causes miniaturisation on the scalp
  • Terminal hair on scalp → vellus hair over successive cycles
  • Men: bitemporal recession + vertex loss (Hamilton-Norwood pattern)
  • Women: diffuse thinning of crown; frontal hairline generally preserved (Ludwig pattern)
  • Primarily autosomal dominant genetic predisposition; worsened by androgen excess
5. Acanthosis Nigricans:
  • Not a direct androgen effect but a marker of insulin resistance associated with PCOS/HAIR-AN
  • Insulin and IGF-1 stimulate keratinocyte and fibroblast proliferation
  • Seen in axillae, neck, groin, under breasts
Idiopathic Hirsutism:
  • Normal circulating androgens, regular ovulatory cycles
  • Caused by increased 5α-reductase activity locally in the follicle
  • Increased end-organ sensitivity of hair follicle to androgens
  • Higher rate in Mediterranean, South Asian, and Middle Eastern populations

CLINICAL FEATURES

1. Hirsutism

  • Definition: Excessive hair growth in women in a male-pattern (androgenic) distribution
  • Differs from hypertrichosis (generalised excess hair, androgen-independent)
  • Distribution: Upper lip > thighs > lower abdomen > upper back; also chin, cheeks, chest, suprapubic area, perianal area
  • Ferriman-Gallwey (mFG) Score:
    • Scores 9 body areas (upper lip, chin/cheeks, chest, upper abdomen, lower abdomen, upper back, lower back, arms, legs)
    • Score 0-4 per area; maximum 36
    • Normal: ≤8; Mild: 8-14; Moderate to severe: ≥15
  • Abrupt/rapid onset → suspect malignancy
  • Severity of hirsutism does not always correlate with degree of androgen excess

2. Acne

  • Comedonal acne in early puberty (9-12 years) is normal; does not need workup unless other features
  • Acne with onset ages 1-7 with virilisation → refer to paediatric endocrinologist
  • Features suggesting hormonal acne:
    • Sudden onset / severe acne
    • Refractory to conventional treatment
    • Predominantly on lower face, jawline, neck
    • Premenstrual flares
    • Irregular menstrual periods
    • Associated hirsutism or alopecia

3. Seborrhoea

  • Oily, shiny skin especially of the face and scalp
  • Scaling and redness (seborrhoeic dermatitis)
  • Present in 100% of SAHA syndrome cases

4. Androgenetic Alopecia (AGA)

  • Women: Ludwig pattern - diffuse central/crown thinning, frontal hairline preserved
  • Men: Hamilton-Norwood pattern - bitemporal + vertex loss
  • Usually slow and progressive
  • Can be acquired in androgen excess states or as autosomal dominant genetic disorder

5. Signs of Virilisation (severe hyperandrogenism)

  • Clitoromegaly
  • Male-pattern balding (frontal recession in women)
  • Deepening of voice
  • Decreased breast size / breast tissue atrophy
  • Increased muscle mass
  • Galactorrhoea (if hyperprolactinaemia)

6. SAHA Syndrome

  • Seborrhoea + Acne + Hirsutism + Androgenetic Alopecia
  • Four subtypes: idiopathic, ovarian, adrenal, hyperprolactinaemic
  • Prevalent in 17.7% of PCOS patients; associated with greater insulin resistance

7. HAIR-AN Syndrome

  • Hyperandrogenism + Insulin Resistance + Acanthosis Nigricans
  • Severe insulin resistance driving androgen excess
  • Diagnosis: impaired GTT result

8. PCOS-specific cutaneous findings

  • Severe truncal hirsutism
  • Axillary acanthosis nigricans (common)
  • Skin tags
  • Associated: obesity, irregular periods, infertility, impaired glucose tolerance, hyperlipidaemia

APPROACH TO DIAGNOSIS

Step 1: History

  • Age of onset, rate of progression (slow = functional; rapid = tumour)
  • Menstrual history (oligomenorrhoea, amenorrhoea)
  • Family history
  • Medications: anabolic steroids, danazol, valproate, synthetic progestins
  • Obstetric history
  • Symptoms of Cushing: weight gain, striae, buffalo hump, easy bruising

Step 2: Physical Examination

  • mFG scoring for hirsutism
  • Signs of virilisation
  • Signs of insulin resistance: acanthosis nigricans, skin tags, central obesity
  • Signs of Cushing: purple striae, moon facies, buffalo hump
  • Thyroid palpation
  • Galactorrhoea (hyperprolactinaemia)

Step 3: Investigation

First-line tests:
TestPurpose
Free testosterone (or total testosterone)Best screening marker; most sensitive biochemical marker of hyperandrogenism
DHEA-SScreens for adrenal androgen source; elevated in adrenal tumours and CAH
LH:FSH ratioRatio >2-3 suggests PCOS
ProlactinScreens for hyperprolactinaemia
TSHRules out hypothyroidism
Fasting glucose/GTTInsulin resistance assessment
17-OHP (early morning)Elevated in 21-hydroxylase deficiency NCAH (>10 ng/mL after ACTH stimulation)
Note: Laboratory evaluation is most accurate when the patient is off oral contraceptives for 4-6 weeks, and tests are drawn before menses.
Second-line (if indicated):
TestIndication
ACTH stimulation testConfirm NCAH (17-OHP >10 ng/mL post-ACTH)
Dexamethasone suppression testDistinguish adrenal vs. ovarian vs. Cushing origin
24-hour urinary cortisol / late-night salivary cortisolRule out Cushing syndrome
Pelvic ultrasoundPCOS (polycystic ovaries), ovarian tumour
CT abdomenAdrenal mass (if DHEA-S 2-3× upper limit)
Pregnancy test (β-hCG)Rule out pregnancy if amenorrhoeic
IGF-1, GHAcromegaly
Red flag values:
  • Total testosterone >200 ng/dL → suspect adrenal or ovarian tumour → urgent imaging
  • DHEA-S 2-3× upper limit → adrenal mass → CT adrenal

Diagnostic Algorithm

The approach follows a branching pathway based on menstrual regularity:
Approach to a patient with hirsutism
Figure: Diagnostic approach to hirsutism - from Fitzpatrick's Dermatology
  • Regular cycles + normal T → Idiopathic hirsutism
  • Regular cycles + elevated T → Idiopathic hyperandrogenism
  • Irregular cycles, no sudden onset → Exclude secondary causes (PCOS, NCAH, SAHA, hypothyroidism, acromegaly, hyperprolactinaemia, HAIR-AN)
  • Sudden onset + virilisation → Suspect malignancy; T >200 ng/dL → imaging for adrenal/ovarian tumour

MANAGEMENT

Management is directed at the underlying cause and at the specific cutaneous manifestation. It involves pharmacological and non-pharmacological approaches.

A. HORMONAL / ANTI-ANDROGEN THERAPY

1. Oral Contraceptive Pills (OCPs)

  • Mechanism: Increase SHBG (reducing free testosterone), suppress LH, reduce ovarian androgen production
  • Preferred formulations: Those containing progestins with low androgenic or antiandrogenic activity (desogestrel, norgestimate) or antiandrogenic progestins (cyproterone acetate, drospirenone)
  • Indications: Hirsutism, hormonal acne, AGA in women with PCOS or ovarian hyperandrogenism
  • Improvement in acne within 3-6 months; hirsutism requires 6-9 months
  • Contraindicated in women >35 years who smoke, or with thromboembolic risk

2. Spironolactone

  • Mechanism: Aldosterone antagonist (potassium-sparing diuretic) with antiandrogen activity; competes for androgen cytosol receptors; also inhibits 5α-reductase; decreases androgen synthesis
  • Dose: 50-200 mg/day
  • Uses: Hirsutism, hormonal acne, AGA in women, seborrhoea
  • Monitor: serum potassium, blood pressure, menstrual irregularity
  • Contraindicated in pregnancy (feminisation of male fetus)
  • Topical spironolactone: Limited evidence for hirsutism

3. Cyproterone Acetate (CPA)

  • Antiandrogen + progestin
  • Used as part of oral contraceptive preparations (not available in the USA)
  • Effective for acne, hirsutism, AGA
  • Often used in combination as Diane-35 (CPA 2 mg + ethinyl oestradiol 35 μg)

4. Finasteride

  • Mechanism: 5α-reductase inhibitor; blocks conversion of testosterone → DHT
  • Dose: 1-5 mg/day
  • Uses: AGA in men (5 mg for FPHL in post-menopausal women - limited benefit in placebo-controlled trials); hirsutism
  • Contraindicated in women of childbearing age (risk of hypospadias/feminisation in male fetus)
  • Side effects in men: decreased libido, erectile dysfunction, depression (may persist after stopping - post-finasteride syndrome); linked to increased risk of high-grade prostate cancer (without increase in absolute risk)

5. Dutasteride

  • Dual 5α-reductase inhibitor (type 1 + type 2)
  • More potent than finasteride
  • Used in hirsutism and AGA

6. Flutamide

  • Androgen receptor antagonist
  • Rarely used due to risk of fatal hepatotoxicity (hepatitis)
  • Risk to male fetus in women of childbearing age

7. Bicalutamide

  • Non-steroidal pure antiandrogen (developed for prostate cancer)
  • Dose: 25 mg/day for PCOS-induced and idiopathic hirsutism
  • Well-tolerated; hepatotoxicity reported at ≥50 mg/day

8. Metformin

  • Insulin sensitiser; improves insulin responsiveness in PCOS
  • Indirect antiandrogen effect by reducing insulin-driven androgen production
  • Improves menstrual irregularity, reduces androgens
  • Adjunct in PCOS with insulin resistance / metabolic syndrome

9. Glucocorticoids

  • For adrenal-origin hyperandrogenism (CAH)
  • Suppresses ACTH, thereby reducing adrenal androgen production
  • Dexamethasone 0.25-0.5 mg at night (low dose to avoid Cushing side effects)
  • Prednisolone 5-7.5 mg/day

10. Clascoterone (Winlevi 1%)

  • Topical antiandrogen (androgen receptor antagonist)
  • Approved for treatment of acne
  • Not well-established for hirsutism

B. MANAGEMENT OF SPECIFIC CONDITIONS

Hirsutism

Cosmetic/Physical methods:
  • Shaving, depilatory creams, waxing, threading - temporary
  • Eflornithine HCl 13.9% cream (Vaniqa): Topical inhibitor of ornithine decarboxylase; slows hair growth; used on face; not permanent; applied twice daily
  • Electrolysis: Uses galvanic current or thermolysis; only permanent method; disadvantages: time-consuming, scarring, follicular hyperpigmentation, pain; regrowth ~40%
  • Laser hair removal:
    • 755-nm Alexandrite laser
    • 800-nm Diode laser
    • 1064-nm Nd:YAG laser (best for darker skin)
    • Intense Pulsed Light (IPL)
    • Works via selective photothermolysis - targets pigmented follicles; requires 3-6 treatment cycles; less effective for fair hair; adverse effects: PIH, folliculitis, paradoxical hypertrichosis, HSV reactivation
Systemic:
  • Spironolactone 100-200 mg/day (first-line for idiopathic hirsutism / PCOS in women)
  • OCP (especially drospirenone or CPA-containing)
  • Finasteride / Dutasteride
  • Metformin (for PCOS-associated)

Hormonal Acne

  • OCP (low-androgenic/antiandrogenic progestins)
  • Spironolactone 50-150 mg/day
  • Cyproterone acetate-containing OCP
  • Clascoterone 1% topical
  • Plus standard topical therapy: retinoids, benzoyl peroxide, topical antibiotics

Androgenetic Alopecia (AGA)

  • Women:
    • Topical minoxidil 2-5% (first-line)
    • Spironolactone (systemic or topical)
    • OCP (antiandrogenic)
    • Finasteride (post-menopausal only - limited evidence)
    • Low-level laser therapy
  • Men:
    • Topical minoxidil 5%
    • Finasteride 1 mg/day
    • Dutasteride 0.5 mg/day
    • Hair transplantation

Seborrhoea

  • Topical antifungals (ketoconazole shampoo)
  • Topical low-potency corticosteroids
  • Antiandrogen therapy if severe / associated with SAHA

Acanthosis Nigricans (in PCOS/HAIR-AN)

  • Weight loss (primary target in obesity)
  • Metformin
  • Lifestyle modification
  • Topical retinoids / keratolytics

C. MANAGEMENT OF SPECIFIC UNDERLYING CAUSES

PCOS

  1. Lifestyle modification: Weight loss (first-line in obese patients) - even 5-10% weight reduction can restore menstrual cycles and reduce androgen levels
  2. Metformin - improves insulin resistance, menstrual regularity
  3. OCP - regulates menstrual cycles, reduces androgens
  4. Spironolactone - for cutaneous manifestations
  5. Clomiphene citrate - if fertility is desired

Non-Classic CAH (21-hydroxylase deficiency)

  • Low-dose glucocorticoids (dexamethasone, prednisolone) to suppress ACTH
  • Antiandrogen therapy (spironolactone, OCP) as alternative or adjunct
  • Antenatal dexamethasone in homozygous female fetuses (to prevent virilisation of external genitalia)
  • Diagnosis confirmed by CYP21 genotyping

Adrenal/Ovarian Tumours

  • Surgical resection (curative)

Cushing Syndrome

  • Treatment of primary cause (surgery for pituitary adenoma - transsphenoidal, adrenal adenoma, ectopic ACTH source)

Hyperprolactinaemia

  • Dopamine agonists: cabergoline, bromocriptine

SUMMARY TABLE: ANTIANDROGENS IN DERMATOLOGY

DrugMechanismMain UsesKey Side EffectsContraindication
SpironolactoneAR antagonist + 5α-RI + ↓ androgen synthesisHirsutism, acne, AGAHyperkalaemia, menstrual irregularity, breast tendernessPregnancy
Cyproterone acetateAR antagonist + progestinHirsutism, acne, AGAHepatotoxicity (high dose), depressionPregnancy
Finasteride5α-RI (type 1+2)AGA (men), hirsutismDecreased libido, ED, depression, post-finasteride syndromePregnancy (teratogenic)
Dutasteride5α-RI dual (type 1+2)AGA, hirsutismSame as finasteridePregnancy
FlutamideAR antagonistHirsutismFatal hepatitisPregnancy, liver disease
BicalutamideAR antagonist (pure non-steroidal)Hirsutism (PCOS, idiopathic)Hepatotoxicity at ≥50 mgPregnancy
OCP↑ SHBG, ↓ LH, antiandrogenicHirsutism, acne, AGAThromboembolism, hypertensionThrombophilia, age >35 + smoking
MetforminInsulin sensitiser (indirect)PCOSGI side effects, lactic acidosisRenal failure
ClascoteroneTopical AR antagonistAcneLocal irritation-
EflornithineOrnithine decarboxylase inhibitorFacial hirsutismLocal irritation-

KEY EXAM POINTS

  1. SAHA syndrome = Seborrhoea + Acne + Hirsutism + Androgenetic Alopecia; 4 subtypes (idiopathic, ovarian, adrenal, hyperprolactinaemic)
  2. HAIR-AN syndrome = Hyperandrogenism + Insulin Resistance + Acanthosis Nigricans
  3. Modified Ferriman-Gallwey score: ≤8 normal; 8-14 mild hirsutism; ≥15 moderate-severe
  4. DHT is the most potent intracellular androgen; formed by 5α-reductase from testosterone
  5. SHBG reduction (by obesity, insulin resistance, progestins) → increased free androgens
  6. Free testosterone is the most sensitive biochemical marker of hyperandrogenism
  7. Testosterone >200 ng/dL → suspect androgen-secreting tumour → urgent imaging
  8. 17-OHP elevation (especially post-ACTH >10 ng/mL) → NCAH (21-hydroxylase deficiency)
  9. Idiopathic hirsutism = normal androgens + regular cycles + increased 5α-reductase activity locally
  10. Abrupt rapid onset of hirsutism = red flag for malignancy
  11. Finasteride contraindicated in women of childbearing age (feminisation of male fetus)
  12. Flutamide - avoid due to fatal hepatotoxicity
  13. Laser hair removal works via selective photothermolysis; Nd:YAG preferred for dark skin; not effective for light/white hair
  14. Eflornithine - topical; inhibits ornithine decarboxylase; slows facial hair growth; not permanent

Sources: Fitzpatrick's Dermatology, 9th Ed., Vol. 1-2 (Ch. 90: Hirsutism; Ch. 137: Hyperandrogenism); Andrews' Diseases of the Skin, 13th Ed. (Ch. 24: Androgen-Dependent Syndromes); Dermatology 2-Volume Set, 5th Ed.

Can you make this notes into download able colourful pdf include all information

Reading File
Running Command

mkdir -p /tmp/workspace/cutaneous-hyperandrogenism && ls /tmp/workspace/

Writing File

~/cutaneous-hyperandrogenism/generate_pdf.py

#!/usr/bin/env python3
"""
Cutaneous Hyperandrogenism - MD Dermatology Notes PDF Generator
Colourful, well-structured, exam-ready PDF using ReportLab
"""

from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm, cm
from reportlab.lib import colors
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, PageBreak, KeepTogether
)
from reportlab.platypus.flowables import BalancedColumns
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.pdfgen import canvas
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate

# ── Colour Palette ──────────────────────────────────────────────────────────
DARK_NAVY     = colors.HexColor("#1A237E")   # Title / major headings
ROYAL_BLUE    = colors.HexColor("#1565C0")   # Section headers
TEAL          = colors.HexColor("#00695C")   # Sub-headings
ORANGE        = colors.HexColor("#E65100")   # Highlight / accent
AMBER         = colors.HexColor("#F57F17")   # Warning / key-point boxes
GREEN_DARK    = colors.HexColor("#2E7D32")   # Management headers
PURPLE        = colors.HexColor("#6A1B9A")   # Special boxes
RED_DARK      = colors.HexColor("#B71C1C")   # Red-flag boxes

# Table header backgrounds
TBL_HDR_NAVY  = colors.HexColor("#283593")
TBL_HDR_TEAL  = colors.HexColor("#00796B")
TBL_HDR_GREEN = colors.HexColor("#388E3C")
TBL_HDR_PURP  = colors.HexColor("#7B1FA2")

# Soft backgrounds for boxes
BOX_YELLOW    = colors.HexColor("#FFFDE7")
BOX_BLUE      = colors.HexColor("#E3F2FD")
BOX_GREEN     = colors.HexColor("#E8F5E9")
BOX_RED       = colors.HexColor("#FFEBEE")
BOX_PURPLE    = colors.HexColor("#F3E5F5")
BOX_TEAL      = colors.HexColor("#E0F2F1")
BOX_ORANGE    = colors.HexColor("#FFF3E0")

PAGE_W, PAGE_H = A4
MARGIN = 18*mm

# ── Page numbering canvas ────────────────────────────────────────────────────
def add_page_decorations(canvas_obj, doc):
    canvas_obj.saveState()
    w, h = A4
    # Header bar
    canvas_obj.setFillColor(DARK_NAVY)
    canvas_obj.rect(0, h - 14*mm, w, 14*mm, fill=1, stroke=0)
    canvas_obj.setFillColor(colors.white)
    canvas_obj.setFont("Helvetica-Bold", 9)
    canvas_obj.drawString(MARGIN, h - 9*mm, "CUTANEOUS HYPERANDROGENISM")
    canvas_obj.setFont("Helvetica", 8)
    canvas_obj.drawRightString(w - MARGIN, h - 9*mm, "MD Dermatology Examination Notes")
    # Footer bar
    canvas_obj.setFillColor(ROYAL_BLUE)
    canvas_obj.rect(0, 0, w, 10*mm, fill=1, stroke=0)
    canvas_obj.setFillColor(colors.white)
    canvas_obj.setFont("Helvetica", 8)
    canvas_obj.drawCentredString(w/2, 3.5*mm, f"Page {doc.page}")
    canvas_obj.drawString(MARGIN, 3.5*mm, "Sources: Fitzpatrick's Dermatology 9e | Andrews' 13e | Dermatology 2-Vol Set 5e")
    canvas_obj.restoreState()

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

    s['doc_title'] = ParagraphStyle(
        'doc_title', parent=base['Normal'],
        fontName='Helvetica-Bold', fontSize=24,
        textColor=colors.white, alignment=TA_CENTER,
        spaceAfter=4, spaceBefore=0, leading=30)

    s['doc_sub'] = ParagraphStyle(
        'doc_sub', parent=base['Normal'],
        fontName='Helvetica', fontSize=12,
        textColor=colors.HexColor("#BBDEFB"), alignment=TA_CENTER,
        spaceAfter=2, leading=16)

    s['section'] = ParagraphStyle(
        'section', parent=base['Normal'],
        fontName='Helvetica-Bold', fontSize=13,
        textColor=colors.white, alignment=TA_LEFT,
        spaceBefore=10, spaceAfter=4, leading=17,
        leftIndent=0, borderPadding=(4, 8, 4, 8))

    s['subsection'] = ParagraphStyle(
        'subsection', parent=base['Normal'],
        fontName='Helvetica-Bold', fontSize=11,
        textColor=TEAL, alignment=TA_LEFT,
        spaceBefore=7, spaceAfter=3, leading=14)

    s['subsubsection'] = ParagraphStyle(
        'subsubsection', parent=base['Normal'],
        fontName='Helvetica-Bold', fontSize=10,
        textColor=ORANGE, alignment=TA_LEFT,
        spaceBefore=5, spaceAfter=2, leading=13)

    s['body'] = ParagraphStyle(
        'body', parent=base['Normal'],
        fontName='Helvetica', fontSize=9.5,
        textColor=colors.HexColor("#212121"),
        alignment=TA_JUSTIFY, spaceBefore=2, spaceAfter=2, leading=14,
        leftIndent=0)

    s['bullet'] = ParagraphStyle(
        'bullet', parent=base['Normal'],
        fontName='Helvetica', fontSize=9.5,
        textColor=colors.HexColor("#212121"),
        alignment=TA_LEFT, spaceBefore=1, spaceAfter=1, leading=13,
        leftIndent=12, bulletIndent=4)

    s['bullet2'] = ParagraphStyle(
        'bullet2', parent=base['Normal'],
        fontName='Helvetica', fontSize=9,
        textColor=colors.HexColor("#424242"),
        alignment=TA_LEFT, spaceBefore=1, spaceAfter=1, leading=12,
        leftIndent=24, bulletIndent=14)

    s['keypoint'] = ParagraphStyle(
        'keypoint', parent=base['Normal'],
        fontName='Helvetica-Bold', fontSize=9.5,
        textColor=AMBER, alignment=TA_LEFT,
        spaceBefore=2, spaceAfter=2, leading=13, leftIndent=4)

    s['redbox'] = ParagraphStyle(
        'redbox', parent=base['Normal'],
        fontName='Helvetica-Bold', fontSize=9.5,
        textColor=RED_DARK, alignment=TA_LEFT,
        spaceBefore=2, spaceAfter=2, leading=13, leftIndent=4)

    s['tbl_hdr'] = ParagraphStyle(
        'tbl_hdr', parent=base['Normal'],
        fontName='Helvetica-Bold', fontSize=9,
        textColor=colors.white, alignment=TA_CENTER, leading=12)

    s['tbl_cell'] = ParagraphStyle(
        'tbl_cell', parent=base['Normal'],
        fontName='Helvetica', fontSize=8.5,
        textColor=colors.HexColor("#212121"), alignment=TA_LEFT, leading=11)

    s['tbl_cell_bold'] = ParagraphStyle(
        'tbl_cell_bold', parent=base['Normal'],
        fontName='Helvetica-Bold', fontSize=8.5,
        textColor=colors.HexColor("#1A237E"), alignment=TA_LEFT, leading=11)

    s['caption'] = ParagraphStyle(
        'caption', parent=base['Normal'],
        fontName='Helvetica-Oblique', fontSize=8,
        textColor=colors.HexColor("#616161"), alignment=TA_CENTER,
        spaceBefore=2, spaceAfter=4, leading=11)

    s['box_title'] = ParagraphStyle(
        'box_title', parent=base['Normal'],
        fontName='Helvetica-Bold', fontSize=10,
        textColor=PURPLE, alignment=TA_LEFT,
        spaceBefore=2, spaceAfter=2, leading=14)

    s['exam_point'] = ParagraphStyle(
        'exam_point', parent=base['Normal'],
        fontName='Helvetica', fontSize=9.5,
        textColor=colors.HexColor("#212121"),
        alignment=TA_LEFT, spaceBefore=1, spaceAfter=1, leading=13,
        leftIndent=8)

    return s


# ── Helper: section header ───────────────────────────────────────────────────
def section_header(text, style, bg_color=ROYAL_BLUE):
    data = [[Paragraph(f"  {text}", style)]]
    t = Table(data, colWidths=[PAGE_W - 2*MARGIN])
    t.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,-1), bg_color),
        ('TOPPADDING', (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
        ('LEFTPADDING', (0,0), (-1,-1), 8),
        ('RIGHTPADDING', (0,0), (-1,-1), 8),
        ('ROUNDEDCORNERS', [4, 4, 4, 4]),
    ]))
    return t

def coloured_box(content_rows, bg_color=BOX_BLUE, border_color=ROYAL_BLUE):
    """Wraps content in a coloured background box."""
    data = [[c] for c in content_rows]
    flat = [[item for sublist in data for item in sublist]]
    inner = []
    for row in content_rows:
        inner.append([row])
    t = Table(inner, colWidths=[PAGE_W - 2*MARGIN - 4])
    t.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,-1), bg_color),
        ('BOX', (0,0), (-1,-1), 1, border_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


# ── Main PDF builder ─────────────────────────────────────────────────────────
def build_pdf(output_path):
    doc = SimpleDocTemplate(
        output_path,
        pagesize=A4,
        leftMargin=MARGIN, rightMargin=MARGIN,
        topMargin=20*mm, bottomMargin=16*mm,
        title="Cutaneous Hyperandrogenism - MD Dermatology Notes",
        author="Orris Medical AI",
        subject="MD Dermatology University Examination Notes"
    )

    s = make_styles()
    story = []
    col_w = PAGE_W - 2*MARGIN

    # ── TITLE PAGE ────────────────────────────────────────────────────────────
    title_bg = Table(
        [[Paragraph("CUTANEOUS HYPERANDROGENISM", s['doc_title'])],
         [Paragraph("Comprehensive Notes for MD Dermatology University Theory Examination", s['doc_sub'])],
         [Spacer(1, 4)],
         [Paragraph("Etiology · Pathogenesis · Clinical Features · Approach · Management", s['doc_sub'])],
         [Spacer(1, 6)],
         [Paragraph("Sources: Fitzpatrick's Dermatology 9e | Andrews' Diseases of the Skin 13e | Dermatology 2-Vol Set 5e", 
                    ParagraphStyle('src', fontName='Helvetica', fontSize=9, textColor=colors.HexColor("#90CAF9"), alignment=TA_CENTER, leading=12))]
        ],
        colWidths=[col_w]
    )
    title_bg.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,-1), DARK_NAVY),
        ('TOPPADDING', (0,0), (-1,-1), 14),
        ('BOTTOMPADDING', (0,0), (-1,-1), 14),
        ('LEFTPADDING', (0,0), (-1,-1), 14),
        ('RIGHTPADDING', (0,0), (-1,-1), 14),
        ('ROUNDEDCORNERS', [8, 8, 8, 8]),
    ]))
    story.append(title_bg)
    story.append(Spacer(1, 10))

    # ── DEFINITION ────────────────────────────────────────────────────────────
    story.append(section_header("1. DEFINITION", s['section'], ROYAL_BLUE))
    story.append(Spacer(1, 4))
    story.append(Paragraph(
        "<b>Cutaneous hyperandrogenism</b> refers to clinical manifestations in the skin, hair, and "
        "sebaceous glands resulting from <b>excessive androgen activity</b> — either due to elevated circulating "
        "androgens <i>or</i> increased end-organ sensitivity to normal androgen levels.",
        s['body']))
    story.append(Spacer(1, 4))

    # SAHA box
    saha_data = [
        [Paragraph("★  SAHA SYNDROME", s['box_title'])],
        [Paragraph("<b>S</b>eborrhoea  +  <b>A</b>cne  +  <b>H</b>irsutism  +  <b>A</b>ndrogenetic Alopecia", s['keypoint'])],
        [Paragraph("Four subtypes: Idiopathic · Ovarian · Adrenal · Hyperprolactinaemic | Prevalence: 17.7% of PCOS patients", s['body'])],
    ]
    story.append(coloured_box([row[0] for row in saha_data], BOX_PURPLE, PURPLE))
    story.append(Spacer(1, 3))

    hair_data = [
        [Paragraph("★  HAIR-AN SYNDROME", ParagraphStyle('ht', fontName='Helvetica-Bold', fontSize=10, textColor=RED_DARK))],
        [Paragraph("<b>H</b>yperandrogenism  +  <b>I</b>nsulin <b>R</b>esistance  +  <b>A</b>canthosis <b>N</b>igricans", s['keypoint'])],
    ]
    story.append(coloured_box([row[0] for row in hair_data], BOX_RED, RED_DARK))
    story.append(Spacer(1, 6))

    # ── ETIOLOGY ─────────────────────────────────────────────────────────────
    story.append(section_header("2. ETIOLOGY", s['section'], ROYAL_BLUE))
    story.append(Spacer(1, 5))

    # Etiology table
    etio_headers = [
        Paragraph("SOURCE", s['tbl_hdr']),
        Paragraph("CONDITION", s['tbl_hdr']),
        Paragraph("KEY FEATURES", s['tbl_hdr'])
    ]

    def ec(txt, bold=False):
        st = s['tbl_cell_bold'] if bold else s['tbl_cell']
        return Paragraph(txt, st)

    etio_data = [
        etio_headers,
        [ec("OVARIAN", bold=True), ec("PCOS ★ Most common", bold=True),
         ec("Biochemical/clinical hyperandrogenism + anovulation; LH:FSH >2-3; polycystic ovaries on USG")],
        [ec(""), ec("Functional ovarian hyperandrogenism"), ec("Ovarian steroidogenic dysregulation")],
        [ec(""), ec("Ovarian neoplasms"), ec("Sertoli-Leydig cell tumour, granulosa-theca cell tumour, hilus cell tumour — low metastatic potential; surgical Rx")],
        [ec(""), ec("Hyperthecosis"), ec("Hyperplasia of theca interna cells; more severe hyperandrogenism than PCOS")],
        [ec(""), ec("HAIR-AN syndrome"), ec("Hyperandrogenism + Insulin Resistance + Acanthosis Nigricans")],
        [ec("ADRENAL", bold=True), ec("NCAH (21-OH deficiency) ★", bold=True),
         ec("CYP21A2 mutation; elevated 17-OHP; late-onset; peripubertal hirsutism, acne, amenorrhoea")],
        [ec(""), ec("Cushing syndrome"), ec("Cortisol excess + ACTH-driven adrenal androgen excess; purple striae, moon facies")],
        [ec(""), ec("Adrenal adenoma"), ec("Secretes testosterone; usually unilateral")],
        [ec(""), ec("Adrenal carcinoma"), ec("Secretes testosterone + DHEA-S + cortisol; rapid-onset virilisation")],
        [ec(""), ec("Premature adrenarche"), ec("Early adrenal androgen secretion before age 8 in girls")],
        [ec("PITUITARY /\nOTHER", bold=True), ec("Hyperprolactinaemia"), ec("Prolactinoma, drugs, hypothyroidism; hirsutism + galactorrhoea")],
        [ec(""), ec("Acromegaly"), ec("Elevated GH + IGF-1; coarsened skin, macroglossia, enlarged hands")],
        [ec(""), ec("Hypothyroidism"), ec("Reduces SHBG → increased free androgens")],
        [ec("IDIOPATHIC", bold=True), ec("Idiopathic hirsutism"), ec("Normal androgens, regular cycles; increased 5α-reductase activity locally (5–15% of cases)")],
        [ec(""), ec("Idiopathic hyperandrogenism"), ec("Elevated androgens, no identifiable source")],
        [ec("DRUGS", bold=True), ec("Androgenic medications"), ec("Exogenous androgens, anabolic steroids, danazol, norgestrel, norethindrone, valproate, minoxidil")],
        [ec("PREGNANCY", bold=True), ec("Pregnancy-related"), ec("Luteoma of pregnancy, hyperreactio luteinalis, fetal aromatase deficiency")],
    ]

    etio_colw = [col_w*0.13, col_w*0.32, col_w*0.55]
    etio_table = Table(etio_data, colWidths=etio_colw, repeatRows=1)
    etio_table.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), TBL_HDR_NAVY),
        ('TEXTCOLOR', (0,0), (-1,0), colors.white),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,0), 9),
        ('ALIGN', (0,0), (-1,0), 'CENTER'),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor("#EEF2FF"), colors.white]),
        ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor("#BDBDBD")),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 5),
        ('RIGHTPADDING', (0,0), (-1,-1), 5),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        # Colour rows by source
        ('BACKGROUND', (0,1), (0,5), colors.HexColor("#E3F2FD")),
        ('BACKGROUND', (0,6), (0,10), colors.HexColor("#E8F5E9")),
        ('BACKGROUND', (0,11), (0,13), colors.HexColor("#F3E5F5")),
        ('BACKGROUND', (0,14), (0,15), colors.HexColor("#FFF3E0")),
        ('BACKGROUND', (0,16), (0,16), colors.HexColor("#FFEBEE")),
        ('BACKGROUND', (0,17), (0,17), colors.HexColor("#FCE4EC")),
    ]))
    story.append(etio_table)
    story.append(Spacer(1, 8))

    # ── PATHOGENESIS ──────────────────────────────────────────────────────────
    story.append(section_header("3. PATHOGENESIS", s['section'], TEAL))
    story.append(Spacer(1, 5))

    story.append(Paragraph("A. Androgen Physiology in Skin", s['subsection']))
    story.append(Paragraph(
        "<b>Sources of androgens in women:</b> Ovaries (testosterone, androstenedione) + "
        "Adrenal cortex (DHEA, DHEA-S, androstenedione) + Peripheral conversion (skin, fat, liver).",
        s['body']))
    story.append(Spacer(1, 3))

    # Key hormones mini table
    horm_headers = [Paragraph("HORMONE", s['tbl_hdr']), Paragraph("POTENCY / ROLE", s['tbl_hdr']), Paragraph("NOTES", s['tbl_hdr'])]
    horm_data = [
        horm_headers,
        [ec("Testosterone"), ec("Principal circulating androgen"), ec("Converted to DHT in target tissues by 5α-reductase")],
        [ec("DHT (5α-dihydrotestosterone)", bold=True), ec("★ Most potent intracellular androgen"), ec("Higher receptor binding affinity than testosterone; acts on sebaceous glands, hair follicles")],
        [ec("DHEA / DHEA-S"), ec("Weak androgens"), ec("Adrenal origin; large quantities; substrate for peripheral conversion")],
        [ec("Androstenedione"), ec("Intermediate"), ec("Converted to testosterone peripherally; ovarian + adrenal source")],
        [ec("Progesterone"), ec("Progestational"), ec("Binds androgen receptor weakly; can have androgenic effects")],
    ]
    horm_colw = [col_w*0.22, col_w*0.30, col_w*0.48]
    horm_table = Table(horm_data, colWidths=horm_colw, repeatRows=1)
    horm_table.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), TBL_HDR_TEAL),
        ('TEXTCOLOR', (0,0), (-1,0), colors.white),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor("#E0F2F1"), colors.white]),
        ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor("#BDBDBD")),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 5),
        ('RIGHTPADDING', (0,0), (-1,-1), 5),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        ('BACKGROUND', (0,2), (-1,2), colors.HexColor("#B2DFDB")),
    ]))
    story.append(horm_table)
    story.append(Spacer(1, 5))

    # 5a reductase and SHBG
    story.append(Paragraph("B. Key Regulatory Mechanisms", s['subsection']))

    enzyme_box = [
        Paragraph("<b>5α-Reductase</b>", s['subsubsection']),
        Paragraph("Converts Testosterone → DHT in peripheral target tissues (sebaceous glands, hair follicles, genital skin)", s['body']),
        Paragraph("• <b>Type 1:</b> Sebaceous glands, liver, skin", s['bullet']),
        Paragraph("• <b>Type 2:</b> Hair follicles, genital skin, prostate", s['bullet']),
        Paragraph("Drugs that inhibit this enzyme: Finasteride (Type 1+2) | Dutasteride (dual Type 1+2)", s['body']),
    ]
    story.append(coloured_box(enzyme_box, BOX_TEAL, TEAL))
    story.append(Spacer(1, 3))

    shbg_box = [
        Paragraph("<b>Sex Hormone-Binding Globulin (SHBG)</b>", s['subsubsection']),
        Paragraph("Binds testosterone and estrogen; only <b>free (unbound) fraction</b> is biologically active.", s['body']),
        Paragraph("SHBG is <b>decreased</b> by (→ more free androgens):", s['body']),
        Paragraph("• Synthetic progestins (norgestrel, norethindrone, norgestimate, desogestrel)", s['bullet']),
        Paragraph("• Obesity · Insulin resistance · Hypothyroidism · Acromegaly", s['bullet']),
        Paragraph("SHBG is <b>increased</b> by: Oestrogens · OCPs (oestrogen component) → less free androgen", s['bullet']),
    ]
    story.append(coloured_box(shbg_box, BOX_BLUE, ROYAL_BLUE))
    story.append(Spacer(1, 5))

    story.append(Paragraph("C. Mechanisms of Individual Cutaneous Manifestations", s['subsection']))

    mech_headers = [Paragraph("MANIFESTATION", s['tbl_hdr']), Paragraph("MECHANISM", s['tbl_hdr'])]
    mech_data = [
        mech_headers,
        [ec("Seborrhoea", bold=True),
         ec("DHT stimulates sebaceous gland hypertrophy + sebum production. Type 1 5α-reductase predominates in sebaceous glands. Androgen receptors densely expressed here.")],
        [ec("Acne vulgaris", bold=True),
         ec("Androgens → ↑ sebum + ↓ linoleic acid → follicular hyperkeratosis → microcomedone → Cutibacterium acnes colonisation → inflammation → papule/pustule/nodule/cyst")],
        [ec("Hirsutism", bold=True),
         ec("DHT activates androgen receptors in hair follicle papilla → conversion of vellus hair (short, fine, unpigmented) to terminal hair (long, pigmented, coarse) in androgen-sensitive areas")],
        [ec("Androgenetic Alopecia", bold=True),
         ec("Paradoxical: same DHT causes miniaturisation on scalp follicles. Terminal scalp hair → vellus hair over successive cycles. Primarily autosomal dominant genetic predisposition; exacerbated by androgen excess")],
        [ec("Acanthosis nigricans", bold=True),
         ec("NOT direct androgen effect. Marker of insulin resistance (PCOS/HAIR-AN). Insulin + IGF-1 stimulate keratinocyte and fibroblast proliferation → velvety hyperpigmented plaques")],
        [ec("Idiopathic hirsutism", bold=True),
         ec("Normal circulating androgens + regular cycles. Caused by increased LOCAL 5α-reductase activity in hair follicle → increased end-organ sensitivity. More common in Mediterranean/South Asian/Middle Eastern populations")],
    ]
    mech_colw = [col_w*0.22, col_w*0.78]
    mech_table = Table(mech_data, colWidths=mech_colw, repeatRows=1)
    mech_table.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), TEAL),
        ('TEXTCOLOR', (0,0), (-1,0), colors.white),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor("#E0F2F1"), colors.white]),
        ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor("#BDBDBD")),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 5),
        ('RIGHTPADDING', (0,0), (-1,-1), 5),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ]))
    story.append(mech_table)
    story.append(Spacer(1, 8))

    # ── CLINICAL FEATURES ────────────────────────────────────────────────────
    story.append(section_header("4. CLINICAL FEATURES", s['section'], ORANGE))
    story.append(Spacer(1, 5))

    # 1. Hirsutism
    story.append(Paragraph("A. Hirsutism", s['subsection']))
    story.append(Paragraph(
        "<b>Definition:</b> Excessive hair growth in women in a <b>male-pattern (androgenic) distribution</b>. "
        "Distinct from hypertrichosis (generalised, androgen-independent).",
        s['body']))

    hir_items = [
        "<b>Distribution:</b> Upper lip > Thighs > Lower abdomen > Upper back; also chin, cheeks, chest, suprapubic, perianal, intergluteal",
        "<b>Abrupt/rapid onset</b> → suspect malignancy (androgen-secreting tumour)",
        "Severity of hirsutism does not always correlate with degree of androgen excess",
        "<b>Ethnicity:</b> Mediterranean > South Asian > Middle Eastern > Asian (lowest prevalence)",
    ]
    for item in hir_items:
        story.append(Paragraph(f"• {item}", s['bullet']))
    story.append(Spacer(1, 4))

    # mFG scoring
    mfg_box = [
        Paragraph("<b>Modified Ferriman-Gallwey (mFG) Score</b>", s['subsubsection']),
        Paragraph("Scores 9 body areas (upper lip, chin/cheeks, chest, upper abdomen, lower abdomen, upper back, lower back, arms, legs)", s['body']),
        Paragraph("Score 0–4 per area (0 = no hair; 4 = extensive growth)  |  Maximum score: 36", s['body']),
    ]
    mfg_score_data = [
        [Paragraph("SCORE", s['tbl_hdr']), Paragraph("INTERPRETATION", s['tbl_hdr'])],
        [ec("≤ 8"), ec("Normal")],
        [ec("8 – 14"), ec("Mild hirsutism")],
        [ec("≥ 15", bold=True), ec("Moderate to Severe hirsutism", bold=True)],
    ]
    mfg_table = Table(mfg_score_data, colWidths=[col_w*0.25, col_w*0.75])
    mfg_table.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), TBL_HDR_PURP),
        ('TEXTCOLOR', (0,0), (-1,0), colors.white),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor("#F3E5F5"), colors.white]),
        ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor("#BDBDBD")),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 5),
        ('RIGHTPADDING', (0,0), (-1,-1), 5),
        ('ALIGN', (0,0), (-1,-1), 'CENTER'),
        ('BACKGROUND', (0,3), (-1,3), colors.HexColor("#EF9A9A")),
    ]))
    story.append(coloured_box(mfg_box + [mfg_table], BOX_PURPLE, PURPLE))
    story.append(Spacer(1, 5))

    story.append(Paragraph("B. Acne (Hormonal)", s['subsection']))
    acne_box = [
        Paragraph("<b>Features suggesting hormonal/hyperandrogenic acne:</b>", s['body']),
        Paragraph("• Sudden onset or severe acne refractory to conventional treatment", s['bullet']),
        Paragraph("• Predominantly lower face / jawline / neck distribution", s['bullet']),
        Paragraph("• Premenstrual flares", s['bullet']),
        Paragraph("• Irregular menstrual periods", s['bullet']),
        Paragraph("• Associated hirsutism, seborrhoea, or alopecia", s['bullet']),
        Paragraph("• Acne onset ages 1–7 with virilisation → refer to paediatric endocrinologist", s['bullet']),
        Paragraph("• Comedonal acne ages 9–12 without other features → normal puberty, no workup needed", s['bullet']),
    ]
    story.append(coloured_box(acne_box, BOX_ORANGE, ORANGE))
    story.append(Spacer(1, 4))

    story.append(Paragraph("C. Seborrhoea", s['subsection']))
    story.append(Paragraph(
        "Oily, shiny skin on face and scalp. Scaling and erythema (seborrhoeic dermatitis). "
        "Present in <b>100% of SAHA syndrome</b> cases.",
        s['body']))
    story.append(Spacer(1, 4))

    story.append(Paragraph("D. Androgenetic Alopecia (AGA)", s['subsection']))
    aga_data = [
        [Paragraph("PATTERN", s['tbl_hdr']), Paragraph("MALES", s['tbl_hdr']), Paragraph("FEMALES", s['tbl_hdr'])],
        [ec("Hair loss pattern", bold=True), ec("Bitemporal recession + vertex loss (Hamilton-Norwood pattern)"), ec("Diffuse crown thinning; frontal hairline PRESERVED (Ludwig pattern)")],
        [ec("Mechanism", bold=True), ec("DHT-driven miniaturisation of scalp follicles"), ec("Same mechanism; genetic predisposition + androgen excess")],
        [ec("Genetics", bold=True), ec("Autosomal dominant (variable penetrance)"), ec("More commonly acquired in androgen excess states")],
    ]
    aga_table = Table(aga_data, colWidths=[col_w*0.18, col_w*0.41, col_w*0.41], repeatRows=1)
    aga_table.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), GREEN_DARK),
        ('TEXTCOLOR', (0,0), (-1,0), colors.white),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor("#E8F5E9"), colors.white]),
        ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor("#BDBDBD")),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 5),
        ('RIGHTPADDING', (0,0), (-1,-1), 5),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ]))
    story.append(aga_table)
    story.append(Spacer(1, 5))

    story.append(Paragraph("E. Signs of Virilisation (Severe Hyperandrogenism)", s['subsection']))
    vir_box = [
        Paragraph("⚠ Signs indicating severe hyperandrogenism — investigate urgently for androgen-secreting tumour:", s['redbox']),
        Paragraph("• Clitoromegaly  •  Male-pattern frontal balding in women  •  Deepening of voice", s['bullet']),
        Paragraph("• Decreased breast size / breast tissue atrophy  •  Increased muscle mass", s['bullet']),
        Paragraph("• Galactorrhoea (if associated hyperprolactinaemia)", s['bullet']),
    ]
    story.append(coloured_box(vir_box, BOX_RED, RED_DARK))
    story.append(Spacer(1, 5))

    story.append(Paragraph("F. PCOS-Specific Cutaneous Findings", s['subsection']))
    story.append(Paragraph("• Severe truncal hirsutism  •  Axillary acanthosis nigricans  •  Skin tags  •  Seborrhoea  •  Hormonal acne", s['bullet']))
    story.append(Paragraph("Associated systemic features: Obesity, oligomenorrhoea/amenorrhoea, infertility, insulin resistance, dyslipidaemia, sleep apnoea, risk of endometrial cancer", s['body']))
    story.append(Spacer(1, 8))

    # ── APPROACH TO DIAGNOSIS ─────────────────────────────────────────────────
    story.append(section_header("5. APPROACH TO DIAGNOSIS", s['section'], PURPLE))
    story.append(Spacer(1, 5))

    story.append(Paragraph("A. History", s['subsection']))
    hist_items = [
        "Age of onset + rate of progression — <b>slow/gradual</b> → functional cause; <b>rapid/abrupt</b> → tumour",
        "Menstrual history: oligomenorrhoea, amenorrhoea, intermenstrual bleeding",
        "Family history of hirsutism, PCOS, or CAH",
        "Medications: anabolic steroids, danazol, valproate, norgestrel, minoxidil, CsA",
        "Obstetric/reproductive history; desire for fertility",
        "Symptoms of Cushing: central weight gain, easy bruising, purple striae, proximal myopathy",
        "Symptoms of hypothyroidism: cold intolerance, constipation, dry skin, weight gain",
        "Galactorrhoea (suggests hyperprolactinaemia)",
    ]
    for item in hist_items:
        story.append(Paragraph(f"• {item}", s['bullet']))
    story.append(Spacer(1, 4))

    story.append(Paragraph("B. Physical Examination", s['subsection']))
    exam_items = [
        "mFG scoring for hirsutism (score 9 body areas; score ≥8 = hirsute)",
        "Signs of virilisation: clitoromegaly, frontal balding, voice change, muscle bulk",
        "Signs of insulin resistance: acanthosis nigricans (axillae, neck, groin), skin tags, central obesity",
        "Signs of Cushing: purple striae, moon facies, buffalo hump, easy bruising",
        "Thyroid palpation — goitre, nodule",
        "Galactorrhoea on breast examination",
        "Pelvic examination — ovarian enlargement (tumour)",
        "Blood pressure (adrenal tumour / Cushing)",
    ]
    for item in exam_items:
        story.append(Paragraph(f"• {item}", s['bullet']))
    story.append(Spacer(1, 5))

    story.append(Paragraph("C. Investigations", s['subsection']))

    # First-line investigations
    inv1_headers = [Paragraph("TEST", s['tbl_hdr']), Paragraph("PURPOSE / INTERPRETATION", s['tbl_hdr'])]
    inv1_data = [
        inv1_headers,
        [ec("Free testosterone ★\n(most sensitive)", bold=True),
         ec("Best screening marker. Elevated in PCOS, ovarian hyperandrogenism, adrenal disorders")],
        [ec("Total testosterone"), ec("T >200 ng/dL → suspect androgen-secreting tumour → urgent imaging")],
        [ec("DHEA-S"), ec("Screens for adrenal androgen source. Elevated in adrenal tumour and CAH. 2-3× upper limit → CT adrenal")],
        [ec("LH : FSH ratio"), ec("Ratio >2-3 → consistent with PCOS")],
        [ec("Prolactin"), ec("Elevated → hyperprolactinaemia; look for prolactinoma")],
        [ec("TSH"), ec("Rules out hypothyroidism as cause of reduced SHBG")],
        [ec("17-OHP (early morning)"), ec("Elevated in 21-hydroxylase deficiency NCAH; >10 ng/mL post-ACTH stimulation → diagnostic")],
        [ec("Fasting glucose / OGTT"), ec("Insulin resistance assessment; impaired GTT → HAIR-AN or PCOS metabolic syndrome")],
        [ec("Lipid profile"), ec("Dyslipidaemia common in PCOS / metabolic syndrome")],
    ]
    note_txt = "<i>★ Lab evaluation most accurate when patient is off OCPs for 4–6 weeks and tests drawn before menses</i>"

    inv1_colw = [col_w*0.27, col_w*0.73]
    inv1_table = Table(inv1_data, colWidths=inv1_colw, repeatRows=1)
    inv1_table.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), TBL_HDR_PURP),
        ('TEXTCOLOR', (0,0), (-1,0), colors.white),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor("#F3E5F5"), colors.white]),
        ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor("#BDBDBD")),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 5),
        ('RIGHTPADDING', (0,0), (-1,-1), 5),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        ('BACKGROUND', (0,2), (-1,2), colors.HexColor("#EF9A9A")),
    ]))
    story.append(Paragraph("First-Line Investigations:", s['subsubsection']))
    story.append(inv1_table)
    story.append(Paragraph(note_txt, s['caption']))
    story.append(Spacer(1, 4))

    # Second-line
    story.append(Paragraph("Second-Line / Confirmatory Investigations:", s['subsubsection']))
    inv2_data = [
        [Paragraph("TEST", s['tbl_hdr']), Paragraph("INDICATION", s['tbl_hdr'])],
        [ec("ACTH stimulation test"), ec("Confirm NCAH: 17-OHP >10 ng/mL post-ACTH → 21-hydroxylase deficiency")],
        [ec("Dexamethasone suppression test (DST)"), ec("Distinguish adrenal vs ovarian vs Cushing origin. Suppressible → adrenal; non-suppressible → Cushing / neoplasm / PCOS")],
        [ec("24-h urine cortisol / late-night salivary cortisol"), ec("Rule out Cushing syndrome")],
        [ec("Pelvic ultrasound (USG)"), ec("PCOS (polycystic ovaries); ovarian tumour; Rotterdam criteria imaging")],
        [ec("CT abdomen / adrenals"), ec("Adrenal mass if DHEA-S 2–3× upper limit; adrenal tumour suspected")],
        [ec("MRI pituitary"), ec("Prolactinoma; Cushing's disease (pituitary source)"),],
        [ec("β-hCG"), ec("Rule out pregnancy if amenorrhoeic")],
        [ec("IGF-1 + GH"), ec("Suspected acromegaly")],
        [ec("CYP21 genotyping"), ec("Confirm diagnosis of NCAH (21-hydroxylase deficiency)")],
    ]
    inv2_table = Table(inv2_data, colWidths=inv1_colw, repeatRows=1)
    inv2_table.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), PURPLE),
        ('TEXTCOLOR', (0,0), (-1,0), colors.white),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor("#EDE7F6"), colors.white]),
        ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor("#BDBDBD")),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 5),
        ('RIGHTPADDING', (0,0), (-1,-1), 5),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ]))
    story.append(inv2_table)
    story.append(Spacer(1, 4))

    # Red flag values box
    rf_box = [
        Paragraph("🔴 RED FLAG INVESTIGATION VALUES", ParagraphStyle('rfh', fontName='Helvetica-Bold', fontSize=10, textColor=RED_DARK)),
        Paragraph("• Testosterone <b>>200 ng/dL</b> → Suspect adrenal or ovarian androgen-secreting tumour → urgent CT/MRI", s['bullet']),
        Paragraph("• DHEA-S <b>2–3× upper limit</b> → Adrenal mass → CT adrenal", s['bullet']),
        Paragraph("• 17-OHP <b>>10 ng/mL</b> post-ACTH stimulation → Non-classic CAH (21-OH deficiency)", s['bullet']),
    ]
    story.append(coloured_box(rf_box, BOX_RED, RED_DARK))
    story.append(Spacer(1, 5))

    # Diagnostic algorithm description
    story.append(Paragraph("D. Diagnostic Algorithm (Approach to Hirsutism)", s['subsection']))
    algo_box = [
        Paragraph("Step 1 — <b>Regular menstrual cycle?</b>", s['body']),
        Paragraph("YES → <b>Normal T</b>: Idiopathic hirsutism  |  <b>Elevated T</b>: Idiopathic hyperandrogenism", s['bullet']),
        Paragraph("NO → Is onset sudden ± virilisation?", s['bullet']),
        Paragraph("     YES → Consider malignancy (imaging for adrenal/pelvic mass); T >200 ng/dL", s['bullet2']),
        Paragraph("     NO → Exclude secondary causes:", s['bullet2']),
        Paragraph("           PCOS · NCAH · Cushing syndrome · Hypothyroidism · Acromegaly ·", s['bullet2']),
        Paragraph("           Hyperprolactinaemia · SAHA syndrome · HAIR-AN · Pregnancy · Medications", s['bullet2']),
        Spacer(1, 3),
        Paragraph("Step 2 — <b>Confirm androgen excess</b> (free testosterone; DHEA-S)", s['body']),
        Paragraph("Step 3 — <b>Localise source</b> (dexamethasone suppression test; ACTH stimulation; imaging)", s['body']),
        Paragraph("Step 4 — <b>Treatment based on aetiology</b> + symptomatic management", s['body']),
    ]
    story.append(coloured_box(algo_box, BOX_YELLOW, AMBER))
    story.append(Spacer(1, 8))

    # ── MANAGEMENT ───────────────────────────────────────────────────────────
    story.append(section_header("6. MANAGEMENT", s['section'], GREEN_DARK))
    story.append(Spacer(1, 5))

    story.append(Paragraph("A. General Principles", s['subsection']))
    story.append(Paragraph(
        "Management is directed at: (1) treating the <b>underlying cause</b>, and (2) managing individual "
        "<b>cutaneous manifestations</b>. Involves pharmacological (hormonal, antiandrogen) and non-pharmacological approaches.",
        s['body']))
    story.append(Spacer(1, 4))

    # Antiandrogen drugs master table
    story.append(Paragraph("B. Antiandrogen and Hormonal Pharmacotherapy", s['subsection']))

    drug_headers = [
        Paragraph("DRUG", s['tbl_hdr']),
        Paragraph("MECHANISM", s['tbl_hdr']),
        Paragraph("DOSE / USES", s['tbl_hdr']),
        Paragraph("KEY SIDE EFFECTS", s['tbl_hdr']),
        Paragraph("CONTRA-\nINDICATION", s['tbl_hdr']),
    ]

    drugs = [
        ["Spironolactone\n★ First-line",
         "AR antagonist + 5α-RI + ↓ androgen synthesis",
         "50–200 mg/day\nHirsutism, acne, AGA, seborrhoea",
         "Hyperkalaemia, menstrual irregularity, breast tenderness, polyuria",
         "Pregnancy; renal failure; hyperkalaemia"],
        ["Oral Contra-\nceptive Pills (OCP)",
         "↑ SHBG, ↓ LH → ↓ ovarian androgen; antiandrogenic progestins",
         "Drospirenone- or CPA-containing preferred\nHirsutism, acne, AGA in women",
         "Thromboembolism, hypertension, nausea, mood changes",
         "Thrombophilia; age >35 + smoking; migraine with aura"],
        ["Cyproterone\nAcetate (CPA)",
         "AR antagonist + progestin",
         "2 mg (in Diane-35) or 50–100 mg\nAcne, hirsutism, AGA",
         "Hepatotoxicity (high dose), depression, decreased libido",
         "Pregnancy; liver disease; meningioma"],
        ["Finasteride",
         "5α-RI (Type 1+2)\nBlocks T → DHT",
         "1 mg/day (AGA men)\n5 mg/day (hirsutism)\nPost-menopausal AGA (limited evidence)",
         "↓ Libido, erectile dysfunction, depression, gynecomastia. Post-finasteride syndrome (persists after stopping)",
         "PREGNANCY (feminises male fetus); women of childbearing age"],
        ["Dutasteride",
         "Dual 5α-RI (Type 1 + Type 2)\nMore potent than finasteride",
         "0.5 mg/day\nAGA in men; hirsutism",
         "Same as finasteride",
         "Pregnancy"],
        ["Flutamide\n⚠ AVOID",
         "Pure AR antagonist",
         "Rarely used\nHirsutism",
         "★ FATAL HEPATOTOXICITY\nRisk to male fetus",
         "Pregnancy; liver disease"],
        ["Bicalutamide",
         "Non-steroidal pure AR antagonist",
         "25 mg/day\nPCOS/idiopathic hirsutism",
         "Hepatotoxicity at ≥50 mg/day",
         "Pregnancy"],
        ["Metformin",
         "Insulin sensitiser\nIndirectly ↓ androgen production",
         "500–1500 mg/day\nPCOS with insulin resistance",
         "GI side effects, lactic acidosis (rare)",
         "Renal failure; contrast procedures"],
        ["Clascoterone\n(Winlevi 1%)",
         "Topical AR antagonist",
         "Topical cream BD\nAcne (FDA-approved)",
         "Local skin irritation",
         "—"],
        ["Eflornithine\n(Vaniqa 13.9%)",
         "Topical ornithine decarboxylase inhibitor\n→ slows hair growth",
         "Apply BD to face\nFacial hirsutism (adjunct; not permanent)",
         "Local irritation, burning, stinging",
         "—"],
        ["Glucocorticoids\n(prednisolone /\ndexamethasone)",
         "↓ ACTH → ↓ adrenal androgen production",
         "Prednisolone 5–7.5 mg/day or\nDexamethasone 0.25–0.5 mg at night\nCAH / adrenal hyperandrogenism",
         "Cushing side effects (long-term), osteoporosis, immunosuppression",
         "Active infections; use minimum effective dose"],
    ]

    drug_col_w = [col_w*0.14, col_w*0.19, col_w*0.22, col_w*0.25, col_w*0.20]
    drug_table_data = [drug_headers]
    for d in drugs:
        drug_table_data.append([Paragraph(txt, s['tbl_cell_bold'] if i == 0 else s['tbl_cell'])
                                 for i, txt in enumerate(d)])

    drug_table = Table(drug_table_data, colWidths=drug_col_w, repeatRows=1)
    row_bg = [colors.HexColor("#E8F5E9"), colors.white]
    drug_table.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), TBL_HDR_GREEN),
        ('TEXTCOLOR', (0,0), (-1,0), colors.white),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,0), 8),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), row_bg),
        ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor("#BDBDBD")),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 4),
        ('RIGHTPADDING', (0,0), (-1,-1), 4),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        # Highlight flutamide row (row 6) in red
        ('BACKGROUND', (0,6), (-1,6), colors.HexColor("#FFCDD2")),
        # Highlight spironolactone (row 1) lightly
        ('BACKGROUND', (0,1), (-1,1), colors.HexColor("#C8E6C9")),
    ]))
    story.append(drug_table)
    story.append(Spacer(1, 8))

    # Management of specific manifestations
    story.append(Paragraph("C. Management of Specific Cutaneous Manifestations", s['subsection']))
    story.append(Spacer(1, 3))

    # Hirsutism management
    story.append(Paragraph("1. Hirsutism", s['subsubsection']))

    hirs_mgmt = [
        Paragraph("<b>Physical / Cosmetic Methods (temporary):</b>", s['body']),
        Paragraph("• Shaving, threading, waxing, depilatory creams (fast; not permanent)", s['bullet']),
        Paragraph("<b>Eflornithine 13.9% cream:</b> Topical ornithine decarboxylase inhibitor; applied twice daily on face; slows growth (not permanent); improvement in 6–8 weeks", s['bullet']),
        Spacer(1, 3),
        Paragraph("<b>Laser Hair Removal:</b>", s['body']),
        Paragraph("• Mechanism: Selective photothermolysis — targets melanin in pigmented hair follicles", s['bullet']),
        Paragraph("• Devices: 755-nm Alexandrite | 800-nm Diode | 1064-nm Nd:YAG (preferred for dark skin) | Intense Pulsed Light (IPL)", s['bullet']),
        Paragraph("• Requires 3–6 treatment cycles; not effective for light/white/grey hair", s['bullet']),
        Paragraph("• Adverse effects: Post-inflammatory hyperpigmentation (PIH), folliculitis, HSV reactivation, paradoxical hypertrichosis (rare)", s['bullet']),
        Spacer(1, 3),
        Paragraph("<b>Electrolysis:</b>", s['body']),
        Paragraph("• Only truly permanent hair removal method", s['bullet']),
        Paragraph("• Types: Galvanic (chemical), thermolysis (heat), blend", s['bullet']),
        Paragraph("• Disadvantages: Time-consuming, painful, risk of scarring and follicular hyperpigmentation; regrowth ~40%", s['bullet']),
        Spacer(1, 3),
        Paragraph("<b>Systemic Therapy:</b>", s['body']),
        Paragraph("• Spironolactone 100–200 mg/day (first-line for idiopathic hirsutism / PCOS)", s['bullet']),
        Paragraph("• OCP with drospirenone or CPA", s['bullet']),
        Paragraph("• Finasteride / Dutasteride", s['bullet']),
        Paragraph("• Metformin (PCOS with insulin resistance)", s['bullet']),
    ]
    story.append(coloured_box(hirs_mgmt, BOX_GREEN, GREEN_DARK))
    story.append(Spacer(1, 4))

    story.append(Paragraph("2. Hormonal Acne", s['subsubsection']))
    acne_mgmt = [
        Paragraph("• OCP (drospirenone- or CPA-containing preferred)", s['bullet']),
        Paragraph("• Spironolactone 50–150 mg/day", s['bullet']),
        Paragraph("• Cyproterone acetate-containing OCP (Diane-35)", s['bullet']),
        Paragraph("• Clascoterone 1% cream (topical AR antagonist — FDA approved)", s['bullet']),
        Paragraph("• Plus standard topical therapy: Retinoids + Benzoyl peroxide ± Topical antibiotics", s['bullet']),
        Paragraph("• Oral isotretinoin for severe nodulo-cystic disease", s['bullet']),
    ]
    story.append(coloured_box(acne_mgmt, BOX_ORANGE, ORANGE))
    story.append(Spacer(1, 4))

    story.append(Paragraph("3. Androgenetic Alopecia (AGA)", s['subsubsection']))
    aga_mgmt_data = [
        [Paragraph("WOMEN", s['tbl_hdr']), Paragraph("MEN", s['tbl_hdr'])],
        [ec("Topical minoxidil 2–5% (first-line)"), ec("Topical minoxidil 5% (first-line)")],
        [ec("Spironolactone (systemic or topical)"), ec("Finasteride 1 mg/day")],
        [ec("OCP with antiandrogenic progestin"), ec("Dutasteride 0.5 mg/day")],
        [ec("Finasteride (post-menopausal; limited evidence)"), ec("Hair transplantation (FUE/FUT)")],
        [ec("Low-level laser therapy (LLLT)"), ec("Low-level laser therapy (LLLT)")],
        [ec("Platelet-rich plasma (PRP) injections"), ec("Platelet-rich plasma (PRP) injections")],
    ]
    aga_mgmt_table = Table(aga_mgmt_data, colWidths=[col_w*0.5, col_w*0.5], repeatRows=1)
    aga_mgmt_table.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), GREEN_DARK),
        ('TEXTCOLOR', (0,0), (-1,0), colors.white),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor("#E8F5E9"), colors.white]),
        ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor("#BDBDBD")),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 5),
        ('RIGHTPADDING', (0,0), (-1,-1), 5),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ]))
    story.append(aga_mgmt_table)
    story.append(Spacer(1, 5))

    # Disease-specific management
    story.append(Paragraph("D. Management by Underlying Aetiology", s['subsection']))

    disease_data = [
        [Paragraph("CONDITION", s['tbl_hdr']), Paragraph("SPECIFIC MANAGEMENT", s['tbl_hdr'])],
        [ec("PCOS", bold=True),
         ec("1. Lifestyle modification + weight loss (5–10% wt loss restores cycles)\n"
            "2. Metformin (insulin resistance, menstrual regulation)\n"
            "3. OCP (cycle regulation, cutaneous hyperandrogenism)\n"
            "4. Spironolactone (cutaneous features)\n"
            "5. Clomiphene citrate (if fertility desired)\n"
            "6. Bariatric surgery (severe obesity)")],
        [ec("Non-Classic CAH\n(21-OH deficiency)", bold=True),
         ec("1. Low-dose glucocorticoids: Dexamethasone 0.25–0.5 mg/night or prednisolone 5–7.5 mg/day (suppress ACTH)\n"
            "2. OCP + antiandrogen therapy as alternative or adjunct\n"
            "3. Antenatal dexamethasone (homozygous female fetuses → prevent virilisation)\n"
            "4. CYP21 genotyping to confirm; genetic counselling")],
        [ec("Adrenal / Ovarian\nTumour", bold=True),
         ec("Surgical resection (curative).\nSertoli-Leydig, granulosa-theca, hilus cell tumours: low metastatic potential; surgery adequate")],
        [ec("Cushing Syndrome", bold=True),
         ec("Treat primary cause:\n• Pituitary adenoma → Transsphenoidal surgery\n• Adrenal adenoma → Adrenalectomy\n• Ectopic ACTH → Resect primary + ketoconazole/metyrapone")],
        [ec("Hyperprolactinaemia", bold=True),
         ec("Dopamine agonists: Cabergoline (first-line) or Bromocriptine\nIf prolactinoma: cabergoline often shrinks tumour; surgery if resistant")],
        [ec("Hypothyroidism", bold=True),
         ec("Thyroxine replacement → SHBG normalises → free androgen levels fall")],
        [ec("Acromegaly", bold=True),
         ec("Transsphenoidal surgery + Somatostatin analogues (octreotide, lanreotide) + Pegvisomant (GH antagonist)")],
        [ec("Drug-induced", bold=True),
         ec("Withdraw causative agent if possible")],
        [ec("Idiopathic Hirsutism", bold=True),
         ec("Spironolactone (first-line) or OCP. Laser hair removal / electrolysis. Eflornithine cream.")],
    ]
    disease_colw = [col_w*0.21, col_w*0.79]
    disease_table = Table(disease_data, colWidths=disease_colw, repeatRows=1)
    disease_table.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), TBL_HDR_NAVY),
        ('TEXTCOLOR', (0,0), (-1,0), colors.white),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor("#E8EAF6"), colors.white]),
        ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor("#BDBDBD")),
        ('TOPPADDING', (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
        ('LEFTPADDING', (0,0), (-1,-1), 5),
        ('RIGHTPADDING', (0,0), (-1,-1), 5),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        ('BACKGROUND', (0,1), (-1,1), colors.HexColor("#DCEDC8")),
        ('BACKGROUND', (0,2), (-1,2), colors.HexColor("#E8EAF6")),
        ('BACKGROUND', (0,3), (-1,3), colors.HexColor("#FFEBEE")),
    ]))
    story.append(disease_table)
    story.append(Spacer(1, 8))

    # ── KEY EXAM POINTS ───────────────────────────────────────────────────────
    story.append(section_header("7. HIGH-YIELD EXAM POINTS", s['section'], AMBER))
    story.append(Spacer(1, 5))

    exam_points = [
        ("<b>SAHA syndrome</b> = Seborrhoea + Acne + Hirsutism + Androgenetic Alopecia; 4 subtypes (idiopathic, ovarian, adrenal, hyperprolactinaemic); 17.7% of PCOS patients"),
        ("<b>HAIR-AN syndrome</b> = Hyperandrogenism + Insulin Resistance + Acanthosis Nigricans"),
        ("<b>mFG score</b>: ≤8 normal | 8–14 mild hirsutism | ≥15 moderate-severe hirsutism"),
        ("<b>DHT</b> is the most potent intracellular androgen; produced by 5α-reductase from testosterone"),
        ("<b>SHBG reduction</b> (obesity, insulin resistance, progestins) → ↑ free androgens → cutaneous features"),
        ("<b>Free testosterone</b> is the most sensitive biochemical marker of hyperandrogenism"),
        ("<b>Testosterone >200 ng/dL</b> → suspect androgen-secreting tumour → urgent CT/MRI"),
        ("<b>17-OHP >10 ng/mL</b> post-ACTH stimulation → NCAH (21-hydroxylase deficiency, CYP21A2 mutation)"),
        ("<b>Idiopathic hirsutism</b> = normal androgens + regular cycles + increased local 5α-reductase activity"),
        ("<b>Abrupt rapid onset of hirsutism</b> = red flag for malignancy"),
        ("<b>Finasteride</b> is CONTRAINDICATED in women of childbearing age (feminisation of male fetus)"),
        ("<b>Flutamide</b> — avoid due to fatal hepatotoxicity"),
        ("<b>Bicalutamide</b> — hepatotoxicity at ≥50 mg/day; safe at 25 mg/day"),
        ("<b>Laser hair removal</b>: works via selective photothermolysis; Nd:YAG 1064 nm preferred for dark skin; NOT effective for light/white/grey hair"),
        ("<b>Eflornithine</b> — topical ornithine decarboxylase inhibitor; slows facial hair growth; not permanent"),
        ("<b>Electrolysis</b> — only truly PERMANENT hair removal; regrowth rate ~40%"),
        ("<b>PCOS treatment</b>: weight loss first-line (obese); metformin; OCP; spironolactone; clomiphene if fertility desired"),
        ("<b>NCAH treatment</b>: low-dose glucocorticoids (dexamethasone 0.25–0.5 mg/night) to suppress ACTH"),
        ("<b>Spironolactone</b> — first-line antiandrogen in dermatology; monitor potassium; contraindicated in pregnancy"),
        ("<b>Acanthosis nigricans</b> in hyperandrogenism = marker of insulin resistance, NOT a direct androgen effect"),
    ]

    exam_box_rows = [Paragraph("★ KEY POINTS FOR EXAM", ParagraphStyle('kph', fontName='Helvetica-Bold', fontSize=11, textColor=AMBER))]
    for i, pt in enumerate(exam_points, 1):
        exam_box_rows.append(Paragraph(f"<b>{i}.</b> {pt}", s['exam_point']))
    story.append(coloured_box(exam_box_rows, BOX_YELLOW, AMBER))
    story.append(Spacer(1, 8))

    # ── QUICK REFERENCE TABLE ─────────────────────────────────────────────────
    story.append(section_header("8. QUICK REFERENCE: ANTIANDROGENS IN DERMATOLOGY", s['section'], DARK_NAVY))
    story.append(Spacer(1, 5))

    qr_headers = [
        Paragraph("DRUG", s['tbl_hdr']),
        Paragraph("MECHANISM", s['tbl_hdr']),
        Paragraph("MAIN USES", s['tbl_hdr']),
        Paragraph("KEY CAUTION", s['tbl_hdr']),
    ]
    qr_drugs = [
        ["Spironolactone", "AR antagonist + 5α-RI + ↓ synthesis", "Hirsutism, acne, AGA ♀", "Hyperkalaemia; CONTRAINDICATED in pregnancy"],
        ["Cyproterone acetate", "AR antagonist + progestin", "Hirsutism, acne, AGA ♀", "Hepatotoxicity (high dose)"],
        ["Finasteride", "5α-RI (Type 1+2)", "AGA ♂; hirsutism", "TERATOGENIC — contraindicated in pregnancy"],
        ["Dutasteride", "5α-RI dual (Type 1+2)", "AGA ♂; hirsutism", "Same as finasteride"],
        ["Flutamide ⚠", "AR antagonist", "Hirsutism (rarely)", "FATAL HEPATOTOXICITY — rarely used"],
        ["Bicalutamide", "Non-steroidal AR antagonist", "Hirsutism (PCOS/idiopathic)", "Hepatotoxicity ≥50 mg/day"],
        ["OCP", "↑ SHBG; ↓ LH; antiandrogenic progestins", "Hirsutism, acne, AGA ♀", "Thromboembolism; smoking + age >35"],
        ["Metformin", "Insulin sensitiser (indirect)", "PCOS", "Renal failure; GI side effects"],
        ["Clascoterone 1%", "Topical AR antagonist", "Acne (FDA approved)", "Local irritation"],
        ["Eflornithine 13.9%", "Topical ODC inhibitor", "Facial hirsutism (slows growth)", "Local irritation; not permanent"],
    ]
    qr_data = [qr_headers]
    for d in qr_drugs:
        qr_data.append([Paragraph(d[0], s['tbl_cell_bold'])] + [Paragraph(x, s['tbl_cell']) for x in d[1:]])

    qr_colw = [col_w*0.17, col_w*0.22, col_w*0.22, col_w*0.39]
    qr_table = Table(qr_data, colWidths=qr_colw, repeatRows=1)
    qr_table.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), DARK_NAVY),
        ('TEXTCOLOR', (0,0), (-1,0), colors.white),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor("#EEF2FF"), colors.white]),
        ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor("#BDBDBD")),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 5),
        ('RIGHTPADDING', (0,0), (-1,-1), 5),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        ('BACKGROUND', (0,5), (-1,5), colors.HexColor("#FFCDD2")),  # flutamide
    ]))
    story.append(qr_table)
    story.append(Spacer(1, 6))

    # Footer note
    story.append(HRFlowable(width=col_w, thickness=1, color=ROYAL_BLUE))
    story.append(Spacer(1, 3))
    story.append(Paragraph(
        "<b>References:</b> Fitzpatrick's Dermatology 9th Ed (Vol. 1–2) | Andrews' Diseases of the Skin, Clinical Dermatology 13th Ed | "
        "Dermatology 2-Volume Set 5th Ed | Harrison's Principles of Internal Medicine 22nd Ed (2025)",
        ParagraphStyle('ref', fontName='Helvetica-Oblique', fontSize=8, textColor=colors.HexColor("#616161"),
                       alignment=TA_CENTER, leading=11)))

    # Build
    doc.build(story, onFirstPage=add_page_decorations, onLaterPages=add_page_decorations)
    print(f"PDF generated: {output_path}")


if __name__ == "__main__":
    build_pdf("/tmp/workspace/cutaneous-hyperandrogenism/Cutaneous_Hyperandrogenism_MD_Derm_Notes.pdf")
Running Command

cd /tmp/workspace/cutaneous-hyperandrogenism && python generate_pdf.py 2>&1

Running Command

ls -lh /tmp/workspace/cutaneous-hyperandrogenism/

Your colourful PDF is ready for download:

Cutaneous Hyperandrogenism MD Derm Notes

PDF Document · PDF


What's inside the PDF (38 KB, A4, fully formatted):
SectionContent
Title PageDark navy banner with full title and source citations
1. DefinitionSAHA syndrome and HAIR-AN syndrome in coloured highlight boxes
2. EtiologyFull colour-coded table — Ovarian / Adrenal / Pituitary / Idiopathic / Drug-induced / Pregnancy causes
3. PathogenesisKey hormones table, 5α-reductase and SHBG mechanism boxes, mechanisms of each cutaneous manifestation
4. Clinical FeaturesHirsutism (mFG scoring table), hormonal acne, seborrhoea, AGA, virilisation red-flag box, SAHA, HAIR-AN, PCOS features
5. ApproachHistory, examination, first-line + second-line investigations, red-flag lab values, diagnostic algorithm flow
6. ManagementFull antiandrogen pharmacotherapy table (11 drugs), hirsutism (laser/electrolysis/eflornithine/systemic), acne, AGA, disease-specific management (PCOS, NCAH, tumour, Cushing, prolactinoma)
7. High-Yield Exam Points20 numbered exam-ready key facts in an amber highlighted box
8. Quick Reference TableAll antiandrogens at a glance — mechanism, uses, key cautions
Header + FooterEvery page has a navy header and blue footer with page number
This is a shared conversation. Sign in to Orris to start your own chat.