Tell about actinic keratosis in detailed

Reading File
Finding Sources
Finding Sources
Searching PubMed

"actinic keratosis"[MeSH Terms] AND treatment

Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Finding Sources
Reading File
Loading Image
Finding Sources
Loading Image
I now have extensive information from multiple authoritative textbooks. Let me compile the comprehensive answer.

Actinic Keratosis (AK) - Comprehensive Overview

Definition and Terminology

Actinic keratosis (AK) is a UV-induced premalignant (intraepidermal) keratinocytic lesion arising on chronically sun-damaged skin. The term "actinic" (from Greek aktis = ray) is preferred over the older synonyms "solar keratosis" and "senile keratosis." The abbreviation SK is avoided because it causes confusion with seborrheic keratosis. AK is fundamentally a form of incipient intraepidermal squamous cell carcinoma (SCC), reflecting atypical keratinocytes confined to the epidermis without invasion of the dermis.
  • Dermatology 2-Volume Set 5e, p. 2254
  • Robbins & Kumar Basic Pathology, p. 890

Epidemiology

AK is one of the most common skin conditions seen by dermatologists worldwide:
  • Affects predominantly fair-skinned individuals (Fitzpatrick phototypes I-III)
  • Incidence increases significantly with age and cumulative UV exposure
  • Highly prevalent in sun-rich regions (Australia, southern USA, southern Europe)
  • Risk groups: elderly, outdoor workers, patients on immunosuppression (organ transplant recipients have dramatically elevated risk), those with a prior history of skin cancer

Etiology and Pathogenesis

The central driver is chronic ultraviolet (UV) radiation, primarily UVB (and to a lesser extent UVA):
  1. UV-induced DNA damage: UV radiation causes pyrimidine dimer formation and characteristic C→T and CC→TT transition mutations
  2. TP53 mutation: The key molecular event. UV-induced mutations in the TP53 tumor suppressor gene are found in AKs and are identical to those found in cutaneous SCC - supporting AK as a true precursor lesion
  3. Field cancerization: Multiple AKs arise within a zone of diffusely UV-damaged "field" skin that harbors sub-clinical TP53 mutations throughout the epidermis
  4. CDKN2A (p16) loss: Additional genetic hits leading to clonal expansion
  5. Immune evasion: Chronic UV exposure suppresses local immune surveillance, facilitating clonal outgrowth of mutant keratinocytes
  • Robbins & Kumar Basic Pathology, p. 890

Clinical Features

Typical appearance:
  • Rough erythematous macule or papule with adherent white-to-yellow scale
  • Size: a few millimeters to several centimeters (in confluent photodamaged fields)
  • Often easier to feel than to see - the rough, sandpaper texture detected on palpation is a hallmark
  • Tenderness is common, especially in hypertrophic lesions
Characteristic sites:
  • Face (forehead, temples, malar eminences, nose, upper lip/ears)
  • Bald scalp
  • Superior helices of the ears
  • Dorsal hands and extensor forearms
  • Shins
Actinic keratoses - clinical and histological
Clinical photos (A-D): AK presenting as confluent erythematous plaques on the forehead (A), as subtle early lesions (B), clustered on the bald scalp (C), and hypertrophic variant (D). From Dermatology 2-Volume Set 5e.
Natural history: AKs may spontaneously regress, persist, or progress to invasive cSCC. Regression and reappearance at the same site is documented. The probability of a single AK progressing to invasive cSCC is estimated at 0.1%-20% (widely varying estimates); Robbins quotes 0.1%-2.6% per lesion per year.

Clinical Subtypes

SubtypeFeatures
Classic (atrophic)Pink-red scaly macule/papule; subtle scale on erythematous base
Hypertrophic (hyperkeratotic)Thick papule/plaque with white or yellow-brown scale; may develop a cutaneous horn; hardest to distinguish from early SCC
PigmentedHyperpigmented, reticulated appearance; lacks obvious erythema; mimics lentigo maligna or reticulated seborrheic keratosis
LichenoidMore erythema at the base; pruritic or tender; lichenoid infiltrate on histology
Actinic cheilitisAffects lower vermilion lip; presents as erythematous patches, scale, and leukoplakia; higher SCC risk than skin AKs
BowenoidFull-thickness epidermal atypia; considered SCC in situ (Bowen disease)
  • Dermatology 2-Volume Set 5e, pp. 2254-2255

Histopathology

Key microscopic features:
  1. Basal layer atypia: Cytologic atypia (nuclear pleomorphism, hyperchromasia, increased mitoses) begins in the lower epidermis, particularly the basal cell layer
  2. Parakeratosis: Abnormal retention of nuclei in the stratum corneum (cornified cells retain their nuclei)
  3. Hyperkeratosis: Thickened stratum corneum
  4. Solar elastosis: Thickened blue-gray elastic fibers in the dermis - hallmark of chronic UV damage
  5. Atrophic epidermis (in atrophic variant) or acanthotic/hyperplastic epidermis (in hypertrophic variant)
  6. Sparing at follicular ostia: A useful histological clue - atypia is present in the interfollicular epidermis but spares the adnexal epithelium
Histological grading (Rowert-Huber/KIN classification):
  • KIN I: Atypia confined to the lower third of the epidermis
  • KIN II: Atypia involving the lower two-thirds
  • KIN III / SCC in situ: Full-thickness atypia (Bowen disease) When full-thickness atypia is present (bowenoid AK), the lesion is reclassified as cSCC in situ.
  • Dermatology 2-Volume Set 5e, p. 2255
  • Robbins & Kumar, p. 890

Dermoscopy

Dermoscopy helps distinguish AK subtypes and exclude malignancy:
  • Strawberry pattern (face): Pseudo-network of red lines and dots within a hair follicle pattern - characteristic of AKs on the face; represents dilated vessels around follicular openings
  • White-yellowish scale: Overlying structureless areas
  • Erythematous background
  • In pigmented AKs: annular-granular structures, gray dots/globules - important to exclude lentigo maligna melanoma

Differential Diagnosis

  • Seborrheic keratosis
  • Squamous cell carcinoma (especially from hypertrophic AK)
  • Bowen disease (SCC in situ)
  • Lentigo maligna (for pigmented AK)
  • Psoriatic plaque (for keratotic lesions on extremities)
  • Lichen planus-like keratosis
  • Discoid lupus erythematosus
  • Warts (verruca vulgaris)

Risk of Malignant Transformation

AKs are true precursor lesions of cutaneous squamous cell carcinoma. The key considerations:
  • Risk per lesion per year: ~0.1-2.6%
  • Risk in a patient with many AKs (field cancerization): cumulative risk is substantially higher
  • Signs of progression to invasive SCC: induration, rapid growth, ulceration, bleeding, pain, diameter >1 cm
  • Actinic cheilitis on the lower lip carries a relatively higher malignant transformation rate
  • Immunosuppressed patients (transplant recipients) face dramatically accelerated progression

Treatment

Treatment is divided into lesion-directed (targets individual visible AKs) and field-directed (treats the entire photodamaged field including subclinical lesions).

Lesion-Directed Therapies

1. Cryotherapy (liquid nitrogen)
  • Most widely used office procedure
  • Open spray technique with a single freeze-thaw cycle of 8-10 seconds (hypertrophic lesions need longer; atrophic or thin-skinned areas need shorter)
  • A 1-2 mm freeze margin around the lesion is adequate
  • Cure rates: ~39% for <5-second freeze, ~69% for 5-20 seconds, ~83% for >20-second freeze
  • Side effects: hypopigmentation (more common with longer freeze times), blistering, scarring
2. Curettage and electrodesiccation
  • Appropriate for thick/hypertrophic AKs
  • Provides histologic specimen
3. Shave excision / surgical excision
  • Reserved for lesions suspicious for invasive SCC

Field-Directed Therapies

AgentMechanismRegimenNotes
5-Fluorouracil (5-FU)Pyrimidine antimetabolite; inhibits thymidylate synthase5% cream (Efudex) daily x 4 weeks; 0.5% cream daily x 4 weeksStandard field therapy; causes significant inflammation; better cosmetic clearance
ImiquimodTLR-7/8 agonist; induces interferon-alpha and innate immune response5% cream 3-5x/week x 12-16 weeks; 3.75% cream daily x 2+2 weeks (Zyclara)Immunomodulator; 5% approved for 25 cm² only
Diclofenac 3% gelCOX-2 inhibitor; anti-proliferativeTwice daily x 60-90 days (Solaraze)Milder side effects than 5-FU; good tolerability
Ingenol mebutateInduces necrosis and immune-mediated destruction0.015% gel x 3 days (face/scalp); 0.05% gel x 2 days (trunk/extremities)Very short course; note: EU withdrew approval in 2020 due to SCC risk signal
Photodynamic therapy (PDT)ALA or methyl-ALA → protoporphyrin IX → activated by blue/red light → reactive O₂ speciesOffice procedure; 1-3 hour ALA incubation + 16 min light activationSingle treatment clearance 50-70%; up to 90% with additional sessions; facial lesions respond better; better cosmetic outcome than cryotherapy per Cochrane data
Key evidence summary: A Cochrane review found that 5-FU, imiquimod, ingenol mebutate, and diclofenac have similar overall efficacy but differ in adverse event profiles and cosmetic outcomes. PDT appears to have better cosmetic outcomes than cryotherapy for individual lesions.
  • Textbook of Family Medicine 9e, p. 955
  • Andrews' Diseases of the Skin, p. 1038 (PDT section)
  • Fitzpatrick's Dermatology, p. 1882 (cryosurgery)
  • Sabiston Textbook of Surgery, Treatment section

Dermoscopy-Guided Approach to Management

Dermoscopy helps stratify lesions:
  • Thin/early AK: field treatment
  • Hypertrophic/suspicious for SCC: excision/biopsy first

Prevention and Sun Protection

All patients with AK or cutaneous SCC should receive counseling on:
  • Daily broad-spectrum sunscreen (SPF 30 or higher)
  • Protective clothing: wide-brimmed hats, long sleeves/pants
  • Sun avoidance: especially 10 AM - 4 PM
  • Regular skin surveillance by a dermatologist (typically every 6-12 months)
  • Patients on long-term immunosuppression require more aggressive monitoring

Summary Table

FeatureDetails
CauseChronic UV radiation (UVB > UVA)
Key mutationTP53
AgeElderly; increases with cumulative sun exposure
PhototypeFitzpatrick I-III (fair skin)
SitesFace, bald scalp, dorsal hands, ears, forearms
MorphologyRough, erythematous, scaly macule/papule
HistologyBasal atypia, parakeratosis, hyperkeratosis, solar elastosis
Risk of SCC~0.1-2.6% per lesion per year
1st-line Rx (few lesions)Cryotherapy
1st-line Rx (field)5-FU, imiquimod, PDT, diclofenac
Biopsy indicatedIndurated, large, recurrent, or ulcerated lesions

Create a PDF quick reference guide on AK diagnosis and treatment protocols

Reading File
Running Command

mkdir -p /home/daytona/workspace/ak-guide && ls /home/daytona/workspace/ak-guide

Writing File

~/ak-guide/generate_ak_guide.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import PageBreak

OUTPUT = "/home/daytona/workspace/ak-guide/AK_Quick_Reference_Guide.pdf"

# ── Colour palette ──────────────────────────────────────────────────────────
TEAL       = colors.HexColor("#1A6B72")
TEAL_LIGHT = colors.HexColor("#E6F4F5")
ORANGE     = colors.HexColor("#E07B39")
ORANGE_LT  = colors.HexColor("#FDF0E8")
RED        = colors.HexColor("#C0392B")
RED_LT     = colors.HexColor("#FDEDEC")
GREEN      = colors.HexColor("#1E8449")
GREEN_LT   = colors.HexColor("#E9F7EF")
GREY_DARK  = colors.HexColor("#2C3E50")
GREY_MID   = colors.HexColor("#566573")
GREY_LIGHT = colors.HexColor("#ECF0F1")
WHITE      = colors.white

PAGE_W, PAGE_H = A4
MARGIN = 18 * mm


# ── Document setup ───────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    leftMargin=MARGIN, rightMargin=MARGIN,
    topMargin=20 * mm, bottomMargin=18 * mm,
    title="Actinic Keratosis Quick Reference Guide",
    author="Orris Medical Reference"
)

styles = getSampleStyleSheet()

# Custom styles
def S(name, parent="Normal", **kw):
    return ParagraphStyle(name, parent=styles[parent], **kw)

H1 = S("H1", fontSize=22, textColor=WHITE, fontName="Helvetica-Bold",
        spaceAfter=4, leading=26, alignment=TA_CENTER)
H2 = S("H2", fontSize=12, textColor=WHITE, fontName="Helvetica-Bold",
        spaceAfter=2, leading=15)
H3 = S("H3", fontSize=10, textColor=TEAL, fontName="Helvetica-Bold",
        spaceAfter=3, leading=13)
BODY = S("BODY", fontSize=8.5, textColor=GREY_DARK, leading=12,
         spaceAfter=3, alignment=TA_JUSTIFY)
BODY_SM = S("BODY_SM", fontSize=7.8, textColor=GREY_DARK, leading=11, spaceAfter=2)
BULLET = S("BULLET", fontSize=8.5, textColor=GREY_DARK, leading=12,
           leftIndent=10, spaceAfter=2,
           bulletIndent=2, bulletText="\u2022")
CAPTION = S("CAP", fontSize=7, textColor=GREY_MID, leading=9,
            alignment=TA_CENTER, spaceAfter=4)
WARN = S("WARN", fontSize=8, textColor=RED, fontName="Helvetica-Bold",
         leading=11, spaceAfter=2)
LABEL = S("LABEL", fontSize=7.5, textColor=GREY_MID, fontName="Helvetica-Bold",
          leading=10)
TH = S("TH", fontSize=8, textColor=WHITE, fontName="Helvetica-Bold",
       leading=11, alignment=TA_CENTER)
TD = S("TD", fontSize=8, textColor=GREY_DARK, leading=11, alignment=TA_LEFT)
TD_C = S("TD_C", fontSize=8, textColor=GREY_DARK, leading=11, alignment=TA_CENTER)

USABLE_W = PAGE_W - 2 * MARGIN

# ── Helper: section header band ─────────────────────────────────────────────
def section_header(title, bg=TEAL, icon=""):
    text = f"{icon}  {title}" if icon else title
    tbl = Table([[Paragraph(text, H2)]], colWidths=[USABLE_W])
    tbl.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, -1), bg),
        ("LEFTPADDING",  (0, 0), (-1, -1), 8),
        ("RIGHTPADDING", (0, 0), (-1, -1), 8),
        ("TOPPADDING",   (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING",(0, 0), (-1, -1), 5),
        ("ROUNDEDCORNERS", [4]),
    ]))
    return tbl

def spacer(h=4):
    return Spacer(1, h * mm)

def hr(color=TEAL_LIGHT, thickness=0.8):
    return HRFlowable(width="100%", thickness=thickness, color=color, spaceAfter=3)


# ── PAGE 1 ───────────────────────────────────────────────────────────────────
story = []

# ---- Title banner ----
title_tbl = Table(
    [[Paragraph("ACTINIC KERATOSIS", H1)],
     [Paragraph("Quick Reference Guide for Diagnosis &amp; Treatment", 
                S("sub", fontSize=11, textColor=TEAL_LIGHT, fontName="Helvetica",
                  alignment=TA_CENTER, leading=14))]],
    colWidths=[USABLE_W]
)
title_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0, 0), (-1, -1), TEAL),
    ("TOPPADDING",    (0, 0), (-1, -1), 10),
    ("BOTTOMPADDING", (0, 0), (-1, -1), 10),
    ("LEFTPADDING",   (0, 0), (-1, -1), 12),
    ("RIGHTPADDING",  (0, 0), (-1, -1), 12),
]))
story.append(title_tbl)
story.append(spacer(3))

# ---- Subtitle strip ----
sub_data = [
    [Paragraph("Dermatology Clinical Reference", S("ss", fontSize=7.5, textColor=GREY_MID,
               alignment=TA_CENTER, leading=10)),
     Paragraph("Sources: Fitzpatrick's | Dermatology 5e | Robbins Pathology | Andrews'", 
               S("ss2", fontSize=7.5, textColor=GREY_MID, alignment=TA_CENTER, leading=10))]
]
sub_tbl = Table(sub_data, colWidths=[USABLE_W/2]*2)
sub_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), GREY_LIGHT),
    ("TOPPADDING", (0,0),(-1,-1), 4),
    ("BOTTOMPADDING",(0,0),(-1,-1), 4),
]))
story.append(sub_tbl)
story.append(spacer(4))

# ════════════════════ ROW 1: OVERVIEW + RISK FACTORS ════════════════════
# ---- OVERVIEW box ----
overview_content = [
    [Paragraph("OVERVIEW", S("ovh", fontSize=9, textColor=TEAL, fontName="Helvetica-Bold", leading=12))],
    [Paragraph(
        "<b>Actinic keratosis (AK)</b> is a UV-induced intraepidermal premalignant "
        "keratinocytic lesion arising on chronically sun-damaged skin. AKs are "
        "true precursor lesions of cutaneous squamous cell carcinoma (cSCC). "
        "Atypical keratinocytes are confined to the epidermis; invasion does not "
        "occur until progression to invasive cSCC.",
        BODY_SM
    )],
    [Paragraph(
        "<b>Synonyms:</b> Solar keratosis (non-preferred), senile keratosis (non-preferred). "
        "The abbreviation <i>SK</i> is avoided because it conflicts with seborrheic keratosis.",
        BODY_SM
    )],
    [Paragraph(
        "<b>Malignant transformation risk:</b> 0.1% - 2.6% per lesion per year; "
        "cumulative risk is higher in patients with multiple lesions (field cancerization).",
        BODY_SM
    )],
]
overview_tbl = Table(overview_content, colWidths=[USABLE_W * 0.52])
overview_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), TEAL_LIGHT),
    ("BACKGROUND", (0,1), (-1,-1), colors.white),
    ("BOX", (0,0), (-1,-1), 0.8, TEAL),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("RIGHTPADDING",  (0,0), (-1,-1), 6),
]))

# ---- RISK FACTORS box ----
rf_rows = [
    [Paragraph("RISK FACTORS", S("rfh", fontSize=9, textColor=ORANGE, fontName="Helvetica-Bold", leading=12))],
]
risk_items = [
    ("Patient factors", "Fair skin (Fitzpatrick I-III), elderly, male sex, immunosuppression"),
    ("Sun exposure", "Chronic cumulative UVB > UVA; outdoor workers, geographic latitude"),
    ("Medical Hx", "Prior AK or skin cancer, genodermatoses (xeroderma pigmentosum)"),
    ("Drugs", "Immunosuppressants (cyclosporine, azathioprine) - transplant pts at high risk"),
    ("Infections", "HPV co-infection in immunocompromised"),
]
for label, val in risk_items:
    rf_rows.append([Paragraph(f"<b>{label}:</b> {val}", BODY_SM)])

rf_tbl = Table(rf_rows, colWidths=[USABLE_W * 0.44])
rf_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), ORANGE_LT),
    ("BACKGROUND", (0,1), (-1,-1), colors.white),
    ("BOX", (0,0), (-1,-1), 0.8, ORANGE),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("RIGHTPADDING",  (0,0), (-1,-1), 6),
]))

row1 = Table([[overview_tbl, rf_tbl]], colWidths=[USABLE_W*0.55, USABLE_W*0.45])
row1.setStyle(TableStyle([
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("LEFTPADDING", (0,0), (-1,-1), 0),
    ("RIGHTPADDING", (0,0), (-1,-1), 0),
    ("TOPPADDING", (0,0), (-1,-1), 0),
    ("BOTTOMPADDING", (0,0), (-1,-1), 0),
    ("INNERGRID", (0,0), (-1,-1), 0, colors.white),
]))
story.append(row1)
story.append(spacer(3))

# ════════════════════ CLINICAL FEATURES ════════════════════
story.append(section_header("CLINICAL FEATURES & SUBTYPES"))
story.append(spacer(2))

# Subtype table
st_header = [
    Paragraph("SUBTYPE", TH),
    Paragraph("APPEARANCE", TH),
    Paragraph("KEY FEATURES", TH),
    Paragraph("DIFFERENTIAL", TH),
]
st_rows = [
    ["Classic / Atrophic", "Pink-red macule/papule with fine white scale", "Rough texture on palpation; 'sandpaper feel'", "Psoriasis, eczema"],
    ["Hypertrophic", "Thick papule/plaque; white-yellow scale-crust on erythematous base", "May develop cutaneous horn; most commonly mimics cSCC", "Invasive SCC, wart, seborrheic keratosis"],
    ["Pigmented", "Hyperpigmented, reticulated; may lack obvious erythema", "Dermoscopy needed; grey dots/annular-granular pattern", "Lentigo maligna, seborrheic keratosis"],
    ["Lichenoid", "Erythematous base; similar to classic but more inflamed", "Pruritic/tender; lichenoid infiltrate on histology", "Lichen planus-like keratosis"],
    ["Actinic Cheilitis", "Erythema, scale, leukoplakia on lower vermilion lip", "Higher malignant risk than skin AKs", "Lip SCC, leukoplakia, contact cheilitis"],
    ["Bowenoid (SCC in situ)", "Erythematous scaly plaque; sharp border", "Full-thickness epidermal atypia = Bowen disease", "Psoriasis, SCC in situ"],
]
st_data = [st_header] + [
    [Paragraph(r[0], S("stb", fontSize=7.8, textColor=TEAL, fontName="Helvetica-Bold", leading=11)),
     Paragraph(r[1], BODY_SM),
     Paragraph(r[2], BODY_SM),
     Paragraph(r[3], BODY_SM)] for r in st_rows
]
cw = [USABLE_W * x for x in [0.18, 0.27, 0.32, 0.23]]
st_tbl = Table(st_data, colWidths=cw, repeatRows=1)
st_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), TEAL),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, TEAL_LIGHT]),
    ("BOX",    (0,0), (-1,-1), 0.6, TEAL),
    ("GRID",   (0,0), (-1,-1), 0.3, colors.HexColor("#BFC9CA")),
    ("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(st_tbl)
story.append(spacer(3))

# ════════════════════ DIAGNOSIS PROTOCOL ════════════════════
story.append(section_header("DIAGNOSIS PROTOCOL", bg=GREY_DARK))
story.append(spacer(2))

# 3-column diagnosis layout
col_w = (USABLE_W - 4) / 3

# Column 1: Examination
exam_rows = [
    [Paragraph("STEP 1: EXAMINATION", S("exh", fontSize=8.5, textColor=GREY_DARK, fontName="Helvetica-Bold", leading=12))],
    [Paragraph("<b>Visual inspection + palpation</b><br/>Sandpaper texture is the key tactile clue - many lesions felt before seen.", BODY_SM)],
    [Paragraph("<b>Sites to examine:</b>", BODY_SM)],
    [Paragraph("\u2022 Face (forehead, temples, nose, ears)", BODY_SM)],
    [Paragraph("\u2022 Bald scalp", BODY_SM)],
    [Paragraph("\u2022 Dorsal hands / extensor forearms", BODY_SM)],
    [Paragraph("\u2022 Shins, lower lip (cheilitis)", BODY_SM)],
    [Paragraph("\u2022 Upper chest / V-neck area", BODY_SM)],
    [Paragraph("<b>Note:</b> Background erythema from rosacea or photodamage can mask lesions.", BODY_SM)],
]
exam_tbl = Table(exam_rows, colWidths=[col_w])
exam_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREY_LIGHT),
    ("BOX", (0,0), (-1,-1), 0.6, GREY_MID),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("RIGHTPADDING",  (0,0), (-1,-1), 5),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))

# Column 2: Dermoscopy
derm_rows = [
    [Paragraph("STEP 2: DERMOSCOPY", S("dh", fontSize=8.5, textColor=GREY_DARK, fontName="Helvetica-Bold", leading=12))],
    [Paragraph("<b>Facial AK - Strawberry pattern:</b><br/>Pseudo-network of red lines + dots around follicular openings on erythematous background.", BODY_SM)],
    [Paragraph("<b>Pigmented AK:</b><br/>Annular-granular structures, grey dots/globules; must exclude lentigo maligna.", BODY_SM)],
    [Paragraph("<b>Hypertrophic AK:</b><br/>White-yellow structureless scale overlying vessels; exclude SCC.", BODY_SM)],
    [Paragraph("<b>Tip:</b> Dermoscopy improves diagnostic accuracy and guides biopsy decision.", BODY_SM)],
]
derm_tbl = Table(derm_rows, colWidths=[col_w])
derm_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREY_LIGHT),
    ("BOX", (0,0), (-1,-1), 0.6, GREY_MID),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("RIGHTPADDING",  (0,0), (-1,-1), 5),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))

# Column 3: Biopsy indications
biopsy_rows = [
    [Paragraph("STEP 3: BIOPSY INDICATIONS", S("bh", fontSize=8.5, textColor=RED, fontName="Helvetica-Bold", leading=12))],
    [Paragraph("<b>Biopsy is mandatory when:</b>", BODY_SM)],
    [Paragraph("\u2022 Lesion is indurated or firm", BODY_SM)],
    [Paragraph("\u2022 Rapid growth", BODY_SM)],
    [Paragraph("\u2022 Ulceration or spontaneous bleeding", BODY_SM)],
    [Paragraph("\u2022 Diameter &gt;1 cm", BODY_SM)],
    [Paragraph("\u2022 Recurrence after topical therapy", BODY_SM)],
    [Paragraph("\u2022 Diagnosis uncertain (suspect melanoma)", BODY_SM)],
    [Paragraph("\u2022 Immunosuppressed patient", BODY_SM)],
    [Paragraph("<b>Preferred:</b> Shave or punch biopsy including dermis to assess invasion depth.", BODY_SM)],
]
biopsy_tbl = Table(biopsy_rows, colWidths=[col_w])
biopsy_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), RED_LT),
    ("BOX", (0,0), (-1,-1), 0.8, RED),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("RIGHTPADDING",  (0,0), (-1,-1), 5),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))

diag_row = Table([[exam_tbl, derm_tbl, biopsy_tbl]], colWidths=[col_w+2]*3)
diag_row.setStyle(TableStyle([
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("LEFTPADDING",   (0,0), (-1,-1), 1),
    ("RIGHTPADDING",  (0,0), (-1,-1), 1),
    ("TOPPADDING",    (0,0), (-1,-1), 0),
    ("BOTTOMPADDING", (0,0), (-1,-1), 0),
]))
story.append(diag_row)
story.append(spacer(3))

# ════════════════════ HISTOPATHOLOGY ════════════════════
story.append(section_header("HISTOPATHOLOGY", bg=GREY_DARK))
story.append(spacer(2))

histo_data = [
    [Paragraph("FEATURE", TH), Paragraph("DESCRIPTION", TH),
     Paragraph("KIN GRADE", TH), Paragraph("SIGNIFICANCE", TH)],
    ["Basal cell atypia", "Nuclear pleomorphism, hyperchromasia, increased mitoses in lower epidermis",
     "KIN I (lower 1/3)", "Earliest change; minimal invasion risk"],
    ["Parakeratosis", "Retention of nuclei in stratum corneum",
     "All grades", "Abnormal cornification; hallmark of AK"],
    ["Hyperkeratosis", "Thickened stratum corneum",
     "All grades", "More prominent in hypertrophic variant"],
    ["Solar elastosis", "Blue-gray thickened elastic fibres in dermis",
     "All grades", "Marker of chronic UV damage"],
    ["Mid-epidermal atypia", "Atypia extending to middle third of epidermis",
     "KIN II", "Moderate risk"],
    ["Full-thickness atypia", "Atypia throughout entire epidermis (bowenoid change)",
     "KIN III = SCC in situ", "High risk; reclassify as Bowen disease"],
    ["Follicular sparing", "Atypia spares adnexal epithelium",
     "AK (not SCC)", "Useful to distinguish AK from invasive SCC"],
]
h_data = [[Paragraph(c if isinstance(c, str) else c, 
           BODY_SM if i > 0 else TH) 
           for c in row] for i, row in enumerate(histo_data)]
histo_tbl = Table(h_data, colWidths=[USABLE_W*x for x in [0.22, 0.34, 0.22, 0.22]])
histo_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREY_DARK),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, GREY_LIGHT]),
    ("BOX",   (0,0), (-1,-1), 0.6, GREY_DARK),
    ("GRID",  (0,0), (-1,-1), 0.3, colors.HexColor("#BFC9CA")),
    ("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(histo_tbl)

story.append(PageBreak())

# ════════════════════ PAGE 2 ════════════════════

# ---- Continuation header ----
cont_tbl = Table([[Paragraph("ACTINIC KERATOSIS - Quick Reference Guide", 
                   S("cont", fontSize=10, textColor=TEAL, fontName="Helvetica-Bold",
                     alignment=TA_CENTER, leading=13))]],
                 colWidths=[USABLE_W])
cont_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), TEAL_LIGHT),
    ("TOPPADDING", (0,0),(-1,-1), 5),
    ("BOTTOMPADDING",(0,0),(-1,-1), 5),
    ("BOX", (0,0),(-1,-1), 0.8, TEAL),
]))
story.append(cont_tbl)
story.append(spacer(3))

# ════════════════════ TREATMENT PROTOCOLS ════════════════════
story.append(section_header("TREATMENT PROTOCOLS", bg=TEAL))
story.append(spacer(2))

# Decision guide intro
story.append(Paragraph(
    "Treatment selection is based on the <b>number and distribution of lesions</b>. "
    "Isolated or few lesions (1-5) favour lesion-directed therapy. "
    "Multiple or diffuse lesions within a photodamaged field favour field-directed therapy. "
    "These approaches can be combined.",
    BODY
))
story.append(spacer(2))

# --- LESION-DIRECTED ---
story.append(Paragraph("LESION-DIRECTED THERAPIES (1-5 discrete lesions)", H3))
ld_header = [Paragraph(h, TH) for h in ["TREATMENT", "TECHNIQUE", "EFFICACY", "NOTES / SIDE EFFECTS"]]
ld_rows = [
    ("Cryotherapy\n(Liquid N2)", 
     "Open spray; 1 freeze-thaw cycle\n8-10 sec (standard)\nLonger for hypertrophic; shorter for thin skin\n1-2 mm freeze margin",
     "Complete response:\n<5 sec: ~39%\n5-20 sec: ~69%\n>20 sec: ~83%",
     "Most widely used; fast; office procedure\nSide effects: hypopigmentation, blistering, scarring\nHypertrophic lesions: pre-treat with emollient or curette"),
    ("Curettage +\nElectrodesiccation",
     "Superficial curette to remove AK\nFollow with electrodesiccation of base",
     "High for discrete hypertrophic AKs",
     "Provides tissue specimen for histology\nUseful when SCC cannot be excluded\nMay scar"),
    ("Shave/Punch\nBiopsy + Excision",
     "Shave biopsy for lesions suspicious for SCC\nPunch or excision for deeper assessment",
     "Definitive for single lesions",
     "Mandatory for indurated, ulcerated, or recurrent lesions\nAllows staging if invasive SCC found"),
    ("PDT\n(single lesion)",
     "Topical ALA or mALA (1-3 h)\nBlue or red light activation (~16 min)",
     "Single Tx: 50-70%\n2 sessions: up to 90%\nFacial > acral sites",
     "Better cosmetic outcome than cryotherapy (Cochrane)\nmALA: improved penetration, less pain\nPatient avoids sunlight 48 h post-Tx"),
]
ld_data = [ld_header]
for r in ld_rows:
    ld_data.append([Paragraph(r[0], S("ldb", fontSize=8, textColor=TEAL, fontName="Helvetica-Bold", leading=11)),
                    Paragraph(r[1].replace("\n","<br/>"), BODY_SM),
                    Paragraph(r[2].replace("\n","<br/>"), BODY_SM),
                    Paragraph(r[3].replace("\n","<br/>"), BODY_SM)])
ld_tbl = Table(ld_data, colWidths=[USABLE_W*x for x in [0.18, 0.28, 0.18, 0.36]], repeatRows=1)
ld_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), TEAL),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, TEAL_LIGHT]),
    ("BOX",   (0,0), (-1,-1), 0.6, TEAL),
    ("GRID",  (0,0), (-1,-1), 0.3, colors.HexColor("#BFC9CA")),
    ("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(ld_tbl)
story.append(spacer(3))

# --- FIELD-DIRECTED ---
story.append(Paragraph("FIELD-DIRECTED THERAPIES (multiple/diffuse lesions - field cancerization)", H3))

fd_header = [Paragraph(h, TH) for h in ["AGENT", "MECHANISM", "REGIMEN", "AREA LIMIT", "ADVERSE EFFECTS"]]
fd_rows = [
    ("5-Fluorouracil\n(5-FU)\nEfudex 5%\nCarac 0.5%",
     "Pyrimidine antimetabolite\nInhibits thymidylate\nsynthase; kills\nproliferating cells",
     "5% cream: daily x 4 wks\n0.5% cream: daily x 4 wks\nIf erythema/crust at 2-3 wks,\ncourse may be sufficient",
     "No formal\narea limit\n(prescription\nproduct)",
     "Intense inflammation, erythema,\nerosions, crusting\nHealing takes 2-4 wks post-Tx\nPetroleum jelly reduces discomfort"),
    ("Imiquimod\n5% (Aldara)\n3.75% (Zyclara)",
     "TLR-7/8 agonist\nInduces IFN-alpha\nand innate immune\nresponse",
     "5%: 3-5x/week x 12-16 wks\n3.75%: daily x 2 wks,\nthen 2 wks off,\nthen daily x 2 wks",
     "5%: 25 cm2 only\n3.75%: larger\nareas approved",
     "Local skin reactions (erythema,\nflu-like symptoms\nHypopigmentation at cleared sites\nExpensive; less practical for large areas"),
    ("Diclofenac\n3% gel\n(Solaraze)",
     "COX-2 inhibitor\nAnti-proliferative\nPro-apoptotic",
     "Twice daily x 60-90 days",
     "No formal limit",
     "Milder than 5-FU; good tolerability\nLocal erythema, dryness\nSlower onset of action"),
    ("Photodynamic\nTherapy (PDT)\n(field)",
     "ALA/mALA → PpIX\n→ activated by light\n→ reactive O2 species",
     "ALA 1-3 h incubation\nBlue or red light 16 min\nCan repeat at 4-8 wks",
     "Limited by\npracticality\n(office-based)",
     "Pain/stinging during light activation\nErythema, crusting post-Tx\nPatient must avoid sunlight 48 h\nBest cosmetic outcome"),
    ("Tirbanibulin\n1% ointment",
     "Dual Src kinase /\ntubulin polymerization\ninhibitor",
     "Daily x 5 days\n(face/scalp only)",
     "25 cm2",
     "Local reactions; well-tolerated\nNewer agent (FDA approved 2020)\nShort course is an advantage"),
]
fd_data = [fd_header]
for r in fd_rows:
    fd_data.append([
        Paragraph(r[0].replace("\n","<br/>"), S("fdb", fontSize=7.8, textColor=TEAL, fontName="Helvetica-Bold", leading=11)),
        Paragraph(r[1].replace("\n","<br/>"), BODY_SM),
        Paragraph(r[2].replace("\n","<br/>"), BODY_SM),
        Paragraph(r[3].replace("\n","<br/>"), BODY_SM),
        Paragraph(r[4].replace("\n","<br/>"), BODY_SM),
    ])
fd_tbl = Table(fd_data, colWidths=[USABLE_W*x for x in [0.16, 0.20, 0.22, 0.12, 0.30]], repeatRows=1)
fd_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), TEAL),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, TEAL_LIGHT]),
    ("BOX",   (0,0), (-1,-1), 0.6, TEAL),
    ("GRID",  (0,0), (-1,-1), 0.3, colors.HexColor("#BFC9CA")),
    ("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(fd_tbl)
story.append(spacer(3))

# ════════════════════ CLINICAL DECISION ALGORITHM ════════════════════
story.append(section_header("CLINICAL DECISION ALGORITHM", bg=ORANGE))
story.append(spacer(2))

algo_data = [
    [Paragraph("CLINICAL SCENARIO", S("ah", fontSize=8.5, textColor=WHITE, fontName="Helvetica-Bold", leading=11, alignment=TA_CENTER)),
     Paragraph("FIRST-LINE", S("ah", fontSize=8.5, textColor=WHITE, fontName="Helvetica-Bold", leading=11, alignment=TA_CENTER)),
     Paragraph("ALTERNATIVE", S("ah", fontSize=8.5, textColor=WHITE, fontName="Helvetica-Bold", leading=11, alignment=TA_CENTER)),
     Paragraph("SPECIAL CONSIDERATIONS", S("ah", fontSize=8.5, textColor=WHITE, fontName="Helvetica-Bold", leading=11, alignment=TA_CENTER))],
    ["1-5 discrete, thin AKs", "Cryotherapy", "PDT", "Fastest; most practical in office"],
    ["1-5 hypertrophic AKs", "Cryotherapy (longer freeze) or curettage+ED", "Excision if SCC suspected", "Biopsy first if indurated or ulcerated"],
    ["Multiple AKs, photodamaged field (face/scalp)", "5-FU 5% or Imiquimod", "PDT (better cosmesis)", "Field Tx addresses subclinical lesions"],
    ["Multiple AKs on extremities/trunk", "5-FU or diclofenac", "Cryotherapy per lesion", "PDT less effective at acral sites"],
    ["Actinic cheilitis", "PDT or 5-FU topical", "Laser ablation, vermilionectomy", "Higher SCC risk; close follow-up"],
    ["Immunosuppressed / transplant patient", "5-FU field + cryotherapy for individual lesions", "PDT; consider oral retinoids (chemoprevention)", "Aggressive surveillance q3-6 months; low threshold to biopsy"],
    ["Pigmented AK (melanoma not excluded)", "Biopsy first", "-", "Do NOT treat empirically; exclude lentigo maligna"],
    ["Recurrent / treatment-resistant AK", "Biopsy mandatory", "Combination Tx after histology", "Exclude invasive SCC"],
]
a_data = []
for i, row in enumerate(algo_data):
    if i == 0:
        a_data.append([Paragraph(c, S("ah", fontSize=8.5, textColor=WHITE, fontName="Helvetica-Bold", leading=11)) for c in row])
    else:
        a_data.append([
            Paragraph(row[0], S("asc", fontSize=8, textColor=GREY_DARK, fontName="Helvetica-Bold", leading=11)),
            Paragraph(row[1], S("afl", fontSize=8, textColor=GREEN, fontName="Helvetica-Bold", leading=11)),
            Paragraph(row[2], BODY_SM),
            Paragraph(row[3], BODY_SM),
        ])
algo_tbl = Table(a_data, colWidths=[USABLE_W*x for x in [0.27, 0.21, 0.19, 0.33]], repeatRows=1)
algo_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), ORANGE),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, ORANGE_LT]),
    ("BOX",   (0,0), (-1,-1), 0.6, ORANGE),
    ("GRID",  (0,0), (-1,-1), 0.3, colors.HexColor("#EDBB99")),
    ("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(algo_tbl)
story.append(spacer(3))

# ════════════════════ BOTTOM ROW: Follow-up + Prevention + Red Flags ════════════════════
fu_w = USABLE_W * 0.35
prev_w = USABLE_W * 0.35
rf_w = USABLE_W * 0.30

# Follow-up
fu_content = [
    [Paragraph("FOLLOW-UP SCHEDULE", S("fuh", fontSize=9, textColor=GREEN, fontName="Helvetica-Bold", leading=12))],
    [Paragraph("<b>Standard patients:</b> Full skin exam every 6-12 months", BODY_SM)],
    [Paragraph("<b>Immunosuppressed / transplant:</b> Every 3-6 months minimum", BODY_SM)],
    [Paragraph("<b>After treatment:</b>", BODY_SM)],
    [Paragraph("\u2022 Reassess at 4-8 weeks", BODY_SM)],
    [Paragraph("\u2022 Incomplete clearance: retreat or biopsy", BODY_SM)],
    [Paragraph("\u2022 New lesions in same field: field treatment", BODY_SM)],
    [Paragraph("<b>Cheilitis:</b> Follow every 3-4 months; low biopsy threshold", BODY_SM)],
]
fu_tbl = Table(fu_content, colWidths=[fu_w])
fu_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREEN_LT),
    ("BOX", (0,0), (-1,-1), 0.8, GREEN),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("RIGHTPADDING",  (0,0), (-1,-1), 6),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))

# Prevention
prev_content = [
    [Paragraph("SUN PROTECTION COUNSELLING", S("pvh", fontSize=9, textColor=TEAL, fontName="Helvetica-Bold", leading=12))],
    [Paragraph("<b>Sunscreen:</b> Broad-spectrum SPF 30+ applied daily; reapply every 2 hours outdoors", BODY_SM)],
    [Paragraph("<b>Protective clothing:</b> Wide-brimmed hat, long sleeves, UV-protective clothing (UPF 50+)", BODY_SM)],
    [Paragraph("<b>Behavior:</b> Avoid peak sun (10 AM - 4 PM); seek shade", BODY_SM)],
    [Paragraph("<b>Chemoprevention:</b> Oral retinoids (acitretin) considered in immunosuppressed patients with multiple AKs and high SCC burden", BODY_SM)],
    [Paragraph("<b>Education:</b> Advise patients that new AKs may develop despite treatment - regular surveillance is essential", BODY_SM)],
]
prev_tbl = Table(prev_content, colWidths=[prev_w])
prev_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), TEAL_LIGHT),
    ("BOX", (0,0), (-1,-1), 0.8, TEAL),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("RIGHTPADDING",  (0,0), (-1,-1), 6),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))

# Red Flags
rf_content = [
    [Paragraph("RED FLAGS: SUSPECT SCC", S("rfh2", fontSize=9, textColor=RED, fontName="Helvetica-Bold", leading=12))],
    [Paragraph("\u26a0 Induration or firmness", WARN)],
    [Paragraph("\u26a0 Ulceration or bleeding", WARN)],
    [Paragraph("\u26a0 Diameter &gt;1 cm", WARN)],
    [Paragraph("\u26a0 Rapid growth", WARN)],
    [Paragraph("\u26a0 Perineural symptoms (pain/numbness)", WARN)],
    [Paragraph("\u26a0 Failure of standard topical therapy", WARN)],
    [Paragraph("\u26a0 Lymphadenopathy", WARN)],
    [Paragraph(
        "Any of the above: <b>BIOPSY before or instead of empirical treatment.</b>",
        S("rfb", fontSize=8, textColor=RED, fontName="Helvetica-Bold", leading=11)
    )],
]
rflag_tbl = Table(rf_content, colWidths=[rf_w])
rflag_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), RED_LT),
    ("BOX", (0,0), (-1,-1), 1.0, RED),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("RIGHTPADDING",  (0,0), (-1,-1), 6),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))

bottom_row = Table([[fu_tbl, prev_tbl, rflag_tbl]], 
                   colWidths=[fu_w + 2, prev_w + 2, rf_w + 2])
bottom_row.setStyle(TableStyle([
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("LEFTPADDING",   (0,0), (-1,-1), 1),
    ("RIGHTPADDING",  (0,0), (-1,-1), 1),
    ("TOPPADDING",    (0,0), (-1,-1), 0),
    ("BOTTOMPADDING", (0,0), (-1,-1), 0),
]))
story.append(bottom_row)
story.append(spacer(3))

# ════════════════════ FOOTER ════════════════════
footer_tbl = Table([[
    Paragraph(
        "Sources: Fitzpatrick's Dermatology (Vols 1-2) | Dermatology 2-Volume Set 5e | "
        "Robbins &amp; Kumar Basic Pathology | Andrews' Diseases of the Skin | "
        "Textbook of Family Medicine 9e | Sabiston Textbook of Surgery",
        S("ft", fontSize=6.5, textColor=GREY_MID, leading=9, alignment=TA_CENTER)
    )
]], colWidths=[USABLE_W])
footer_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), GREY_LIGHT),
    ("TOPPADDING", (0,0),(-1,-1), 4),
    ("BOTTOMPADDING",(0,0),(-1,-1), 4),
    ("BOX", (0,0),(-1,-1), 0.5, GREY_MID),
]))
story.append(footer_tbl)

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

cd /home/daytona/workspace/ak-guide && python generate_ak_guide.py 2>&1

Editing File

~/ak-guide/generate_ak_guide.py

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

cd /home/daytona/workspace/ak-guide && python generate_ak_guide.py 2>&1

Editing File

~/ak-guide/generate_ak_guide.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/ak-guide/generate_ak_guide.py'
Reading File
Editing File

~/ak-guide/generate_ak_guide.py

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

cd /home/daytona/workspace/ak-guide && python generate_ak_guide.py 2>&1

Running Command

ls -lh /home/daytona/workspace/ak-guide/AK_Quick_Reference_Guide.pdf

Your PDF quick reference guide is ready:

AK Quick Reference Guide

PDF Document · PDF


Here's what's included across the 2-page A4 guide:
Page 1
  • Title banner with subtitle and source credits
  • Overview - definition, terminology, malignant transformation risk (0.1-2.6%/lesion/year)
  • Risk factors box - patient factors, sun exposure, medications, immunosuppression
  • Clinical Features & Subtypes table - all 6 subtypes (Classic, Hypertrophic, Pigmented, Lichenoid, Actinic Cheilitis, Bowenoid) with appearance, key features, and differential diagnosis
  • Diagnosis Protocol - 3-column layout: Step 1 Examination, Step 2 Dermoscopy (strawberry pattern, pigmented AK), Step 3 Biopsy indications
  • Histopathology table - 8 features including KIN grading, parakeratosis, solar elastosis, follicular sparing
Page 2
  • Lesion-directed therapies - Cryotherapy (with freeze-time efficacy data), Curettage+ED, Excision, PDT
  • Field-directed therapies - 5-FU, Imiquimod (both strengths), Diclofenac, PDT, Tirbanibulin with regimens and area limits
  • Clinical Decision Algorithm - 8 scenarios mapped to first-line and alternative treatments
  • Follow-up schedule (standard vs. immunosuppressed)
  • Sun protection counselling points
  • Red flags for SCC panel in red
This is a shared conversation. Sign in to Orris to start your own chat.