Explain emergency drugs that's adrenaline in detail it's mechanism how it's works and criteria ana protocols before giving in detail way

Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Searching Images

epinephrine adrenaline mechanism adrenergic receptor cardiac arrest anaphylaxis

Reading File
Loading Image
Loading Image
I now have comprehensive textbook content. Let me compile the full, detailed answer:

Adrenaline (Epinephrine) — Complete Emergency Drug Reference

Epinephrine 1:1000 (1 mg/mL) ampoule — the standard formulation used for anaphylaxis

1. What Is Adrenaline?

Adrenaline (epinephrine) is an endogenous catecholamine synthesized by the adrenal medulla. In emergencies it is administered exogenously as a synthetic racemic preparation. It is the single most important drug in emergency medicine, with roles in:
  • Anaphylaxis (first-line, only life-saving treatment)
  • Cardiac arrest (ACLS/PALS — only vasopressor recommended)
  • Symptomatic bradycardia refractory to atropine
  • Septic/cardiogenic shock (vasopressor infusion)
  • Severe bronchospasm

2. Mechanism of Action

Adrenaline is a non-selective adrenergic agonist, stimulating α₁, α₂, β₁, and β₂ receptors. The clinical effects follow directly from receptor pharmacology.

α₁-Adrenergic Effects (vasoconstriction)

EffectClinical benefit
Peripheral vasoconstriction ↑ SVRRaises blood pressure; reverses vasodilatory shock
Coronary and cerebral vasoconstriction (high dose)Directs blood to core during CPR
Mucosal vasoconstrictionReduces angioedema / laryngeal swelling

α₂-Adrenergic Effects

  • Pre-synaptic feedback inhibition of noradrenaline release (minor clinical relevance at therapeutic doses)

β₁-Adrenergic Effects (cardiac stimulation)

EffectClinical benefit
Positive inotropy (↑ force of contraction)Raises cardiac output
Positive chronotropy (↑ heart rate)Increases minute output
Positive dromotropy (↑ AV conduction)Useful in bradycardia/heart block
Increased automaticityCan restore rhythm in asystole/PEA

β₂-Adrenergic Effects (bronchodilation + metabolic)

EffectClinical benefit
Bronchial smooth muscle relaxationReverses bronchoconstriction
Inhibits mast cell degranulationStops ongoing mediator release in anaphylaxis
Glycogenolysis, lipolysisMetabolic stress response
Vasodilation (skeletal muscle)At low doses, mild BP decrease

Cellular Signal Transduction (β-receptor pathway)

β-adrenergic signaling cascade: receptor → Gs protein → adenylyl cyclase → cAMP → PKA → calcium handling → increased rate of contraction, peak force, and rate of relaxation — Harrison's Principles of Internal Medicine
The β-receptor couples to a Gs protein → activates adenylyl cyclase → generates cAMP → activates Protein Kinase A (PKA) → phosphorylates:
  • L-type Ca²⁺ channels → increased Ca²⁺ influx
  • Ryanodine receptors on the sarcoplasmic reticulum → increased Ca²⁺ release
  • Troponin I → accelerates calcium dissociation (faster relaxation)
  • Phospholamban → enhances SR calcium re-uptake
  • Myosin ATPase → more ATP hydrolysis → faster cross-bridge cycling
Net result: increased rate of contraction, peak force, and rate of relaxation (lusitropy).
"The α-adrenergic action (vasoconstriction) increases SVR and PVR. The resultant higher aortic diastolic blood pressure improves coronary perfusion pressure and myocardial blood flow... Epinephrine also increases cerebral blood flow during good-quality CPR because peripheral vasoconstriction directs more flow to the cerebral circulation." — Miller's Anesthesia, 10e

3. Pharmacokinetics

ParameterDetail
Onset (IV)1–2 minutes
Onset (IM)3–8 minutes
Half-life~2–3 minutes (rapidly metabolized by COMT and MAO)
MetabolismLiver, kidney, plasma — methylation (COMT) + oxidative deamination (MAO)
ExcretionRenal (as inactive metabolites: metanephrine, VMA)
StabilityInactivated by alkaline solutions — never mix with sodium bicarbonate

4. Clinical Indications, Criteria, and Protocols


A. ANAPHYLAXIS

Diagnostic Criteria (Table 14-1, Tintinalli's Emergency Medicine)

Anaphylaxis is highly likely when ANY ONE of the following three criteria is met:
Criterion 1: Acute onset of illness (minutes to hours) with skin or mucosal involvement (urticaria, flushing, generalised itching, lip/tongue/uvula edema) AND at least one of:
  • Respiratory distress or hypoxia
  • Hypotension or cardiovascular collapse
  • Associated organ dysfunction (hypotonia, syncope, incontinence)
Criterion 2: Two or more of the following occurring minutes to hours after allergen exposure:
  • Skin and/or mucosal involvement
  • Respiratory compromise
  • Hypotension or associated symptoms
  • Persistent GI cramps or vomiting
Criterion 3: Hypotension after exposure to a known allergen for that patient (even without skin signs)

Common Triggers

Drugs (β-lactams, NSAIDs, vancomycin), foods (nuts, shellfish, eggs), insect stings, latex, contrast media, blood products.

Clinical Features by System

SystemSigns/SymptomsIncidence
SkinUrticaria, angioedema, flushing, pruritus60–90%
RespiratoryWheezing, laryngeal edema, stridor, rhinitis45–60%
ENTThroat fullness, tongue swelling, uvular edema50%
CardiovascularHypotension, chest pain30–35%
GINausea, vomiting, cramps, diarrhea25–30%
NeuroHeadache, seizure5–8%

Anaphylaxis Treatment Protocol

Step 1 — Immediate Assessment (ABC)
  • Airway: examine for angioedema, stridor → intubate early if airway threatened (do not delay — progressive edema can make intubation impossible)
  • Breathing: SpO₂ monitoring, O₂ to maintain saturation >90%
  • Circulation: IV access, cardiac monitor, BP
Step 2 — Decontamination
  • Stop the offending agent if identifiable (stop drug infusion, remove stinger)
  • Do NOT perform gastric lavage for food allergens
Step 3 — EPINEPHRINE (FIRST-LINE — given immediately)
"Epinephrine is the first-line, most effective treatment for anaphylaxis." — Tintinalli's EM
RouteDoseConcentrationNotes
IM (preferred)0.3–0.5 mg (adult)1:1000 (1 mg/mL)Anterolateral thigh — fastest absorption
IM (child)0.01 mg/kg (max 0.5 mg)1:1000
Autoinjector (EpiPen)0.3 mg adult / 0.15 mg child1:1000
IV (severe/arrest)0.1–0.5 mg bolus1:10,000 (0.1 mg/mL)Only in cardiovascular collapse with IV access
IV infusion1 mg in 500 mL NS; start 2–10 mcg/minTitrate to BP
  • Repeat IM dose every 5–15 minutes if no response
  • IM into the anterolateral thigh gives faster and more reliable absorption than deltoid or subcutaneous routes
Why does epinephrine work in anaphylaxis?
  • α₁: Constricts blood vessels → reverses hypotension and reduces mucosal edema/angioedema
  • β₁: Positive inotropy/chronotropy → supports cardiac output
  • β₂: Bronchodilation → reverses bronchoconstriction; also inhibits mast cell degranulation → stops further mediator release
Step 4 — IV Fluids
  • Bolus 1–2 L NS (or LR) rapidly for hypotension
  • Massive fluid shifts occur due to increased vascular permeability
Step 5 — Second-Line Agents (adjuncts only — do NOT replace epinephrine)
DrugDoseRole
Diphenhydramine (H₁ blocker)25–50 mg IV/IMReduces urticaria/pruritus; does NOT treat hypotension or respiratory compromise
Ranitidine/famotidine (H₂ blocker)50 mg IVH₂ blockade complements H₁
Methylprednisolone125 mg IVPrevents biphasic reaction; onset delayed 4–6 h
Salbutamol (nebulised)2.5–5 mgPersistent bronchospasm after epinephrine
Glucagon1–2 mg IVCritical in β-blocker patients who are resistant to epinephrine's β effects
Special Consideration — β-Blockers: Patients on β-blockers may have blunted response to epinephrine. Give glucagon 1–2 mg IV as it bypasses adrenergic receptors and directly activates adenylyl cyclase. Consider atropine for bradycardia. Switch β-blocker to another class at discharge.
Biphasic Reaction Risk:
  • Occurs 3–11 hours after initial episode in 1–20% of patients
  • Observe all anaphylaxis patients for minimum 4–6 hours (8–12 hours if severe)
  • Discharge with prescription for ≥2 epinephrine autoinjectors, antihistamines (5 days), prednisolone (40–60 mg/day for 3–5 days), and allergy referral

B. CARDIAC ARREST

Indications

  • Ventricular fibrillation (VF) or pulseless VT — unresponsive to initial shock
  • Asystole
  • Pulseless electrical activity (PEA)
  • Profoundly symptomatic bradycardia (when atropine fails)

Mechanism in Cardiac Arrest

"Epinephrine may provide the most benefit within the first 15 to 20 minutes of cardiac arrest during the circulatory phase, based on its alpha effects of increasing peripheral vasoconstriction and coronary and cerebral blood flow." — Tintinalli's EM
  • α₁ vasoconstriction raises aortic diastolic pressure → increases coronary perfusion pressure (CPP) → critical determinant of ROSC
  • β₁ stimulation increases automaticity and contractile force if any cardiac activity present
  • Adverse: May worsen myocardial ischemia, increase O₂ demand, induce ventricular ectopy, and cause cerebral vasoconstriction (worsening neurologic outcomes especially after 20 min)

Cardiac Arrest Protocol (Adult — ACLS)

TimingAction
0 minCollapse → CPR (30:2 compressions:ventilations)
ASAPDefibrillate if shockable rhythm (VF/pVT)
After 2nd shock / PEA/AsystoleEpinephrine 1 mg IV/IO
Every 3–5 minRepeat epinephrine 1 mg IV/IO (no maximum number of doses)
Persistent VF/pVTAdd amiodarone 300 mg IV bolus after 3rd shock
ROSC achievedPost-resuscitation care
Dose (Adult Cardiac Arrest):
  • Standard: 1 mg (1:10,000 concentration = 10 mL) IV or IO
  • Flush with ≥20 mL NS and elevate limb after each peripheral IV dose
  • Repeat every 3–5 minutes
  • High-dose epinephrine (2–5 mg) — no benefit over standard dose in survival; not recommended
Pediatric Cardiac Arrest:
  • Dose: 0.01 mg/kg IV/IO (1:10,000), max 1 mg per dose
  • Repeat every 3–5 minutes
  • Evidence for early administration in non-shockable arrest: may not be effective if given >15 minutes after EMS arrival
Route Preference: IV > IO > Central venous. The endotracheal route is no longer recommended (unreliable absorption due to pulmonary edema).

C. BRADYCARDIA (Non-Arrest)

Indication: Haemodynamically unstable bradycardia (hypotension, altered consciousness, chest pain, pulmonary edema) after atropine fails
IV Infusion Protocol:
  • 1 mg in 500 mL NS
  • Start at 2–10 mcg/min
  • Titrate upward every 3–5 minutes to effect
  • Monitor: HR, BP, ECG continuously

D. SEPTIC/CARDIOGENIC SHOCK

"The α causes vasoconstriction, while β has positive inotropic and chronotropic effects. At higher doses, epinephrine has a similar profile (at lower doses, the β effects predominate) but is associated with more adverse effects." — Harrison's Principles of Internal Medicine, 22e
  • Used when noradrenaline is insufficient (second-line vasopressor in septic shock)
  • Also used post-cardiac arrest for myocardial dysfunction
  • Dose: Infusion titrated from 0.01–1 mcg/kg/min
  • Higher doses → predominantly α effects (vasoconstriction)
  • Lower doses → predominantly β effects (inotropy)

5. Adverse Effects

EffectMechanismClinical Significance
Tachycardiaβ₁Most common adverse effect
Hypertensionα₁Can precipitate stroke, pulmonary edema
Ventricular ectopy / VTβ₁ over-stimulationEspecially with high/prolonged doses
Myocardial ischemiaIncreased O₂ demand, α coronary vasoconstrictionRisk in CAD patients
Pulmonary shuntingβ₂ vasodilationWorsens V/Q mismatch
Cerebral vasoconstrictionα₁ (high dose)May worsen neurologic outcome post-arrest
Anxiety, tremor, headacheCNS/PNS stimulationCommon at lower doses
Hyperglycaemiaβ₂ glycogenolysisMonitor in diabetics
Tissue necrosisα₁ extravasationUse central/IO route; treat extravasation with phentolamine

6. Contraindications and Cautions

SituationConsideration
AnaphylaxisNO absolute contraindications — epinephrine is always given
Cardiac arrestNo absolute contraindications
HypertensionCaution in non-emergency use
Coronary artery diseaseIncreased ischemia risk; caution with infusions
HyperthyroidismEnhanced sensitivity
β-blockersReduced β-response → give glucagon; α effects may be exaggerated
Alkaline IV solutionsDo not mix — inactivated
PheochromocytomaRelative CI — can precipitate hypertensive crisis

7. Concentration Guide — Critical for Safety

ConcentrationRatioUse
1 mg/mL1:1000Anaphylaxis (IM), nebulisation
0.1 mg/mL1:10,000Cardiac arrest (IV), haemodynamic infusions
0.01 mg/mL1:100,000Local anaesthesia additive
⚠️ Medication error risk: Always confirm the concentration before administration. Administering 1:1000 IV instead of 1:10,000 delivers 10× the intended dose and can cause hypertensive crisis, arrhythmia, or death.

8. Summary — Decision Framework

EMERGENCY PRESENTATION
        │
        ├── ANAPHYLAXIS?
        │   ├── Epinephrine 0.3–0.5 mg IM (1:1000) anterolateral thigh
        │   ├── Repeat q5–15 min if needed
        │   ├── IV fluids, O₂, airway management
        │   └── Antihistamines + corticosteroids (adjunct only)
        │
        ├── CARDIAC ARREST (VF/pVT/PEA/Asystole)?
        │   ├── CPR + defibrillation (shockable rhythm)
        │   ├── Epinephrine 1 mg IV/IO (1:10,000)
        │   ├── Repeat every 3–5 min
        │   └── Amiodarone for refractory shockable rhythm
        │
        ├── BRADYCARDIA (haemodynamically unstable, atropine failed)?
        │   └── Epinephrine infusion 2–10 mcg/min IV, titrate
        │
        └── SEPTIC/CARDIOGENIC SHOCK (refractory)?
            └── Epinephrine infusion 0.01–1 mcg/kg/min, titrate

Sources: Tintinalli's Emergency Medicine: A Comprehensive Study Guide, 9e | Miller's Anesthesia, 10e | Harrison's Principles of Internal Medicine, 22e | Roberts and Hedges' Clinical Procedures in Emergency Medicine | Fuster and Hurst's The Heart, 15e

Create a quick reference PDF on epinephrine dosing and protocols for emergency use

Reading File
Running Command

ls -la /home/daytona/workspace/

Running Command

mkdir -p /home/daytona/workspace/epinephrine-qr && python3 -c "import reportlab; print('reportlab ok')" && python3 -c "from reportlab.lib.pagesizes import A4; print('A4 ok')"

Writing File

~/epinephrine-qr/build_pdf.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_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import PageBreak

# ── Colour palette ──────────────────────────────────────────────────────────
RED         = colors.HexColor("#C0392B")
DARK_RED    = colors.HexColor("#922B21")
AMBER       = colors.HexColor("#E67E22")
GREEN       = colors.HexColor("#1E8449")
DARK_GREEN  = colors.HexColor("#145A32")
BLUE        = colors.HexColor("#1A5276")
LIGHT_BLUE  = colors.HexColor("#D6EAF8")
LIGHT_RED   = colors.HexColor("#FADBD8")
LIGHT_AMBER = colors.HexColor("#FDEBD0")
LIGHT_GREEN = colors.HexColor("#D5F5E3")
LIGHT_GREY  = colors.HexColor("#F2F3F4")
MID_GREY    = colors.HexColor("#BDC3C7")
DARK_GREY   = colors.HexColor("#2C3E50")
WHITE       = colors.white
BLACK       = colors.black

W, H = A4  # 595.27 x 841.89 pt

# ── Styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

def S(name, **kw):
    return ParagraphStyle(name, **kw)

TITLE = S("TITLE",
    fontSize=22, fontName="Helvetica-Bold", textColor=WHITE,
    alignment=TA_CENTER, spaceAfter=2)

SUBTITLE = S("SUBTITLE",
    fontSize=11, fontName="Helvetica", textColor=WHITE,
    alignment=TA_CENTER, spaceAfter=0)

H1 = S("H1",
    fontSize=11, fontName="Helvetica-Bold", textColor=WHITE,
    alignment=TA_LEFT, spaceBefore=4, spaceAfter=2)

H2 = S("H2",
    fontSize=9.5, fontName="Helvetica-Bold", textColor=DARK_GREY,
    spaceBefore=3, spaceAfter=1)

BODY = S("BODY",
    fontSize=8.5, fontName="Helvetica", textColor=DARK_GREY,
    spaceBefore=1, spaceAfter=1, leading=11)

BODY_B = S("BODY_B",
    fontSize=8.5, fontName="Helvetica-Bold", textColor=DARK_GREY,
    spaceBefore=1, spaceAfter=1, leading=11)

WARN = S("WARN",
    fontSize=8, fontName="Helvetica-Bold", textColor=RED,
    alignment=TA_CENTER, spaceBefore=2, spaceAfter=2)

FOOTER = S("FOOTER",
    fontSize=7, fontName="Helvetica", textColor=MID_GREY,
    alignment=TA_CENTER)

TBL_HDR = S("TBL_HDR",
    fontSize=8, fontName="Helvetica-Bold", textColor=WHITE,
    alignment=TA_CENTER, leading=10)

TBL_CELL = S("TBL_CELL",
    fontSize=8, fontName="Helvetica", textColor=DARK_GREY,
    alignment=TA_LEFT, leading=10)

TBL_CELL_B = S("TBL_CELL_B",
    fontSize=8, fontName="Helvetica-Bold", textColor=DARK_GREY,
    alignment=TA_LEFT, leading=10)

TBL_CELL_C = S("TBL_CELL_C",
    fontSize=8, fontName="Helvetica", textColor=DARK_GREY,
    alignment=TA_CENTER, leading=10)

ALERT = S("ALERT",
    fontSize=8.5, fontName="Helvetica-Bold", textColor=DARK_RED,
    alignment=TA_CENTER, spaceBefore=3, spaceAfter=3)

# ── Helper: section header bar ───────────────────────────────────────────────
def section_bar(title, bg=BLUE, text_color=WHITE):
    data = [[Paragraph(title, S("tmp", fontSize=10, fontName="Helvetica-Bold",
                                 textColor=text_color, alignment=TA_LEFT))]]
    t = Table(data, colWidths=[W - 28*mm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("LEFTPADDING",  (0,0), (-1,-1), 6),
        ("RIGHTPADDING", (0,0), (-1,-1), 6),
        ("TOPPADDING",   (0,0), (-1,-1), 4),
        ("BOTTOMPADDING",(0,0), (-1,-1), 4),
        ("ROUNDEDCORNERS", [3]),
    ]))
    return t

# ── Helper: two-column layout ────────────────────────────────────────────────
def two_col(left_content, right_content, left_w=None, right_w=None):
    total = W - 28*mm
    if left_w is None:
        left_w = total * 0.49
    if right_w is None:
        right_w = total * 0.49
    gap = total - left_w - right_w
    data = [[left_content, right_content]]
    t = Table(data, colWidths=[left_w, right_w])
    t.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),
    ]))
    return t

# ── Document ─────────────────────────────────────────────────────────────────
out_path = "/home/daytona/workspace/epinephrine-qr/Epinephrine_Quick_Reference.pdf"

doc = SimpleDocTemplate(
    out_path,
    pagesize=A4,
    leftMargin=14*mm, rightMargin=14*mm,
    topMargin=14*mm, bottomMargin=14*mm,
)

story = []

# ═══════════════════════════════════════════════════════════════════════════
# HEADER BANNER
# ═══════════════════════════════════════════════════════════════════════════
header_data = [
    [Paragraph("⚕ EPINEPHRINE (ADRENALINE)", TITLE)],
    [Paragraph("Emergency Dosing & Protocol Quick Reference", SUBTITLE)],
    [Paragraph("For trained healthcare professionals only  |  Always confirm dose/concentration before administration", SUBTITLE)],
]
header_tbl = Table(header_data, colWidths=[W - 28*mm])
header_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), RED),
    ("TOPPADDING",    (0,0), (-1,-1), 6),
    ("BOTTOMPADDING", (0,0), (-1,-1), 6),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("RIGHTPADDING",  (0,0), (-1,-1), 8),
    ("LINEBELOW",     (0,-1), (-1,-1), 2, DARK_RED),
]))
story.append(header_tbl)
story.append(Spacer(1, 4*mm))

# ═══════════════════════════════════════════════════════════════════════════
# CONCENTRATION GUIDE — CRITICAL SAFETY BOX
# ═══════════════════════════════════════════════════════════════════════════
story.append(section_bar("⚠  CONCENTRATION GUIDE — KNOW BEFORE YOU DRAW", bg=DARK_RED))
story.append(Spacer(1, 1.5*mm))

conc_data = [
    [Paragraph("Ratio", TBL_HDR), Paragraph("Concentration", TBL_HDR),
     Paragraph("Volume for 1 mg", TBL_HDR), Paragraph("Clinical Use", TBL_HDR)],
    [Paragraph("1:1,000", TBL_CELL_B), Paragraph("1 mg/mL", TBL_CELL_C),
     Paragraph("1 mL", TBL_CELL_C),
     Paragraph("Anaphylaxis IM · Subcutaneous · Nebulisation", TBL_CELL)],
    [Paragraph("1:10,000", TBL_CELL_B), Paragraph("0.1 mg/mL", TBL_CELL_C),
     Paragraph("10 mL", TBL_CELL_C),
     Paragraph("Cardiac arrest IV/IO · Haemodynamic infusions", TBL_CELL)],
    [Paragraph("1:100,000", TBL_CELL_B), Paragraph("0.01 mg/mL", TBL_CELL_C),
     Paragraph("100 mL", TBL_CELL_C),
     Paragraph("Local anaesthesia additive (not emergency)", TBL_CELL)],
]
conc_tbl = Table(conc_data, colWidths=[28*mm, 32*mm, 32*mm, None])
conc_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), DARK_RED),
    ("BACKGROUND",    (0,1), (-1,1), LIGHT_RED),
    ("BACKGROUND",    (0,2), (-1,2), LIGHT_AMBER),
    ("BACKGROUND",    (0,3), (-1,3), LIGHT_GREY),
    ("BOX",           (0,0), (-1,-1), 0.5, MID_GREY),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
story.append(conc_tbl)

warn_data = [[Paragraph(
    "⛔  NEVER give 1:1,000 IV — this is 10× the IV cardiac arrest dose and can cause fatal hypertension/arrhythmia",
    WARN)]]
warn_tbl = Table(warn_data, colWidths=[W - 28*mm])
warn_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), LIGHT_RED),
    ("BOX",           (0,0), (-1,-1), 1, RED),
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 3),
]))
story.append(Spacer(1, 1*mm))
story.append(warn_tbl)
story.append(Spacer(1, 3*mm))

# ═══════════════════════════════════════════════════════════════════════════
# SECTION 1 — ANAPHYLAXIS  |  SECTION 2 — CARDIAC ARREST  (side by side)
# ═══════════════════════════════════════════════════════════════════════════

col_w = (W - 28*mm - 3*mm) / 2  # two equal columns with 3 mm gap

# ── LEFT: ANAPHYLAXIS ────────────────────────────────────────────────────
ana_story = []

# Header
ah = Table([[Paragraph("🔴  ANAPHYLAXIS", S("tmp", fontSize=10,
    fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_LEFT))]],
    colWidths=[col_w])
ah.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), RED),
    ("LEFTPADDING", (0,0), (-1,-1), 5),
    ("TOPPADDING", (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
]))
ana_story.append(ah)
ana_story.append(Spacer(1, 1.5*mm))

# Diagnosis criteria
ana_story.append(Paragraph("DIAGNOSTIC CRITERIA (any 1 of 3):", H2))
criteria = [
    ["1", "Urticaria/flushing/angioedema + ONE of:\n→ Respiratory distress/hypoxia\n→ Hypotension/collapse\n→ Organ dysfunction (syncope)"],
    ["2", "TWO or more after allergen exposure:\n→ Skin/mucosal involvement\n→ Respiratory compromise\n→ Hypotension\n→ Persistent GI symptoms"],
    ["3", "Hypotension after known allergen\n(even without skin signs)"],
]
crit_data = [
    [Paragraph("Criterion", TBL_HDR), Paragraph("Findings", TBL_HDR)]
] + [
    [Paragraph(r[0], TBL_CELL_B), Paragraph(r[1].replace("\n","<br/>"), TBL_CELL)]
    for r in criteria
]
crit_tbl = Table(crit_data, colWidths=[14*mm, col_w - 14*mm - 2*mm])
crit_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), RED),
    ("BACKGROUND",    (0,1), (-1,1), LIGHT_RED),
    ("BACKGROUND",    (0,2), (-1,2), LIGHT_GREY),
    ("BACKGROUND",    (0,3), (-1,3), LIGHT_RED),
    ("BOX",           (0,0), (-1,-1), 0.5, MID_GREY),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 2),
    ("BOTTOMPADDING", (0,0), (-1,-1), 2),
    ("LEFTPADDING",   (0,0), (-1,-1), 3),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
ana_story.append(crit_tbl)
ana_story.append(Spacer(1, 2*mm))

# Epinephrine dosing
ana_story.append(Paragraph("EPINEPHRINE — FIRST-LINE (give immediately):", H2))
epi_ana = [
    [Paragraph("Patient", TBL_HDR), Paragraph("Route", TBL_HDR),
     Paragraph("Dose", TBL_HDR), Paragraph("Conc.", TBL_HDR)],
    [Paragraph("Adult", TBL_CELL_B), Paragraph("IM thigh", TBL_CELL_C),
     Paragraph("0.3–0.5 mg", TBL_CELL_B), Paragraph("1:1,000", TBL_CELL_C)],
    [Paragraph("Child", TBL_CELL_B), Paragraph("IM thigh", TBL_CELL_C),
     Paragraph("0.01 mg/kg\n(max 0.5 mg)", TBL_CELL_B), Paragraph("1:1,000", TBL_CELL_C)],
    [Paragraph("Collapse/\nArrest", TBL_CELL_B), Paragraph("IV slow", TBL_CELL_C),
     Paragraph("0.1–0.5 mg\nbolus", TBL_CELL_B), Paragraph("1:10,000", TBL_CELL_C)],
    [Paragraph("Infusion", TBL_CELL_B), Paragraph("IV", TBL_CELL_C),
     Paragraph("2–10 mcg/min\ntitrate", TBL_CELL_B), Paragraph("1 mg/500 mL\nNS", TBL_CELL_C)],
]
epi_ana_tbl = Table(epi_ana, colWidths=[18*mm, 18*mm, 24*mm, None])
epi_ana_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), RED),
    ("BACKGROUND",    (0,1), (-1,1), LIGHT_GREEN),
    ("BACKGROUND",    (0,2), (-1,2), LIGHT_GREY),
    ("BACKGROUND",    (0,3), (-1,3), LIGHT_GREEN),
    ("BACKGROUND",    (0,4), (-1,4), LIGHT_GREY),
    ("BOX",           (0,0), (-1,-1), 0.5, MID_GREY),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 2),
    ("BOTTOMPADDING", (0,0), (-1,-1), 2),
    ("LEFTPADDING",   (0,0), (-1,-1), 3),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
ana_story.append(epi_ana_tbl)
ana_story.append(Spacer(1, 1*mm))
ana_story.append(Paragraph("→ Repeat IM every 5–15 min if no response · Site: anterolateral thigh", BODY))
ana_story.append(Spacer(1, 2*mm))

# Stepwise protocol
ana_story.append(Paragraph("TREATMENT STEPS:", H2))
steps = [
    ("1", "AIRWAY", "Intubate early if angioedema/stridor — DO NOT DELAY"),
    ("2", "EPINEPHRINE", "IM 0.3–0.5 mg (1:1,000) anterolateral thigh — IMMEDIATELY"),
    ("3", "O₂", "High-flow O₂ · Target SpO₂ > 90%"),
    ("4", "IV ACCESS", "Large-bore IV · Cardiac monitor · Pulse oximetry"),
    ("5", "IV FLUIDS", "NS 1–2 L bolus for hypotension (increased vascular permeability)"),
    ("6", "ADJUNCTS", "H₁ blocker + H₂ blocker + Corticosteroid (see below)"),
    ("7", "OBSERVE", "≥ 4–6 h · 8–12 h if severe (biphasic risk 3–11 h later)"),
]
step_data = [[Paragraph(s[0], TBL_CELL_B),
              Paragraph(s[1], TBL_CELL_B),
              Paragraph(s[2], TBL_CELL)] for s in steps]
step_tbl = Table(step_data, colWidths=[8*mm, 26*mm, None])
bg_cycle = [LIGHT_RED, LIGHT_GREY]
style_cmds = [
    ("BOX",           (0,0), (-1,-1), 0.5, MID_GREY),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 2),
    ("BOTTOMPADDING", (0,0), (-1,-1), 2),
    ("LEFTPADDING",   (0,0), (-1,-1), 3),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]
for i in range(len(steps)):
    style_cmds.append(("BACKGROUND", (0,i), (-1,i), bg_cycle[i%2]))
step_tbl.setStyle(TableStyle(style_cmds))
ana_story.append(step_tbl)
ana_story.append(Spacer(1, 2*mm))

# Adjunct drugs
ana_story.append(Paragraph("ADJUNCT DRUGS (do NOT replace epinephrine):", H2))
adj = [
    [Paragraph("Drug", TBL_HDR), Paragraph("Dose", TBL_HDR), Paragraph("Note", TBL_HDR)],
    [Paragraph("Diphenhydramine", TBL_CELL), Paragraph("25–50 mg IV/IM", TBL_CELL_B), Paragraph("H₁ blocker · Urticaria/pruritus only", TBL_CELL)],
    [Paragraph("Ranitidine", TBL_CELL), Paragraph("50 mg IV", TBL_CELL_B), Paragraph("H₂ blocker · Complements H₁", TBL_CELL)],
    [Paragraph("Methylprednisolone", TBL_CELL), Paragraph("125 mg IV", TBL_CELL_B), Paragraph("Prevents biphasic · Onset 4–6 h", TBL_CELL)],
    [Paragraph("Salbutamol", TBL_CELL), Paragraph("2.5–5 mg neb", TBL_CELL_B), Paragraph("Persistent bronchospasm", TBL_CELL)],
    [Paragraph("Glucagon", TBL_CELL), Paragraph("1–2 mg IV", TBL_CELL_B), Paragraph("β-BLOCKER patients — bypasses adrenergic receptors", TBL_CELL)],
]
adj_tbl = Table(adj, colWidths=[30*mm, 26*mm, None])
adj_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), RED),
    ("BOX",           (0,0), (-1,-1), 0.5, MID_GREY),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 2),
    ("BOTTOMPADDING", (0,0), (-1,-1), 2),
    ("LEFTPADDING",   (0,0), (-1,-1), 3),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [LIGHT_GREY, WHITE]),
]))
ana_story.append(adj_tbl)

# Build left column as nested table
left_inner = Table([[x] for x in ana_story], colWidths=[col_w])
left_inner.setStyle(TableStyle([
    ("TOPPADDING", (0,0), (-1,-1), 0),
    ("BOTTOMPADDING", (0,0), (-1,-1), 1),
    ("LEFTPADDING", (0,0), (-1,-1), 0),
    ("RIGHTPADDING", (0,0), (-1,-1), 0),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))

# ── RIGHT: CARDIAC ARREST ────────────────────────────────────────────────
ca_story = []

# Header
cah = Table([[Paragraph("🔵  CARDIAC ARREST (ACLS/PALS)", S("tmp", fontSize=10,
    fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_LEFT))]],
    colWidths=[col_w])
cah.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), BLUE),
    ("LEFTPADDING", (0,0), (-1,-1), 5),
    ("TOPPADDING", (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
]))
ca_story.append(cah)
ca_story.append(Spacer(1, 1.5*mm))

# Indications
ca_story.append(Paragraph("INDICATIONS:", H2))
inds = [
    "Ventricular fibrillation (VF) unresponsive to shock",
    "Pulseless VT (pVT) unresponsive to shock",
    "Asystole",
    "Pulseless Electrical Activity (PEA)",
    "Haemodynamically unstable bradycardia (atropine failed)",
]
ind_data = [[Paragraph(f"• {i}", TBL_CELL)] for i in inds]
ind_tbl = Table(ind_data, colWidths=[col_w - 2*mm])
ind_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), LIGHT_BLUE),
    ("BOX",           (0,0), (-1,-1), 0.5, BLUE),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 2),
    ("BOTTOMPADDING", (0,0), (-1,-1), 2),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
]))
ca_story.append(ind_tbl)
ca_story.append(Spacer(1, 2*mm))

# Adult dose
ca_story.append(Paragraph("ADULT CARDIAC ARREST PROTOCOL:", H2))
adult_ca = [
    [Paragraph("Phase", TBL_HDR), Paragraph("Action", TBL_HDR)],
    [Paragraph("0 min", TBL_CELL_B), Paragraph("CPR — 30:2 · Rate ≥ 100/min · Depth ≥ 5 cm", TBL_CELL)],
    [Paragraph("ASAP", TBL_CELL_B), Paragraph("Defibrillate if VF/pVT (do not delay for drugs)", TBL_CELL)],
    [Paragraph("After 2nd shock\nor PEA/Asystole", TBL_CELL_B), Paragraph("Epinephrine 1 mg IV/IO (1:10,000 = 10 mL)\nFlush ≥ 20 mL NS · Continue CPR 30–60 s", TBL_CELL)],
    [Paragraph("Every 3–5 min", TBL_CELL_B), Paragraph("Repeat epinephrine 1 mg IV/IO\n(no maximum dose limit)", TBL_CELL)],
    [Paragraph("Refractory\nVF/pVT", TBL_CELL_B), Paragraph("Amiodarone 300 mg IV bolus after 3rd shock", TBL_CELL)],
    [Paragraph("ROSC", TBL_CELL_B), Paragraph("Post-resuscitation care · Monitor glucose · Temperature", TBL_CELL)],
]
adult_ca_tbl = Table(adult_ca, colWidths=[28*mm, None])
adult_ca_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), BLUE),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [LIGHT_GREY, LIGHT_BLUE]),
    ("BOX",           (0,0), (-1,-1), 0.5, MID_GREY),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 2),
    ("BOTTOMPADDING", (0,0), (-1,-1), 2),
    ("LEFTPADDING",   (0,0), (-1,-1), 3),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
ca_story.append(adult_ca_tbl)
ca_story.append(Spacer(1, 2*mm))

# Paediatric dose
ca_story.append(Paragraph("PAEDIATRIC CARDIAC ARREST DOSE:", H2))
ped_data = [
    [Paragraph("Route", TBL_HDR), Paragraph("Dose", TBL_HDR), Paragraph("Conc.", TBL_HDR), Paragraph("Interval", TBL_HDR)],
    [Paragraph("IV / IO", TBL_CELL_B), Paragraph("0.01 mg/kg\n(max 1 mg)", TBL_CELL_B), Paragraph("1:10,000", TBL_CELL_C), Paragraph("Every\n3–5 min", TBL_CELL_C)],
]
ped_tbl = Table(ped_data, colWidths=[20*mm, 26*mm, 22*mm, None])
ped_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), BLUE),
    ("BACKGROUND",    (0,1), (-1,1), LIGHT_BLUE),
    ("BOX",           (0,0), (-1,-1), 0.5, MID_GREY),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 2),
    ("BOTTOMPADDING", (0,0), (-1,-1), 2),
    ("LEFTPADDING",   (0,0), (-1,-1), 3),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
ca_story.append(ped_tbl)
ca_story.append(Paragraph("→ Give early in non-shockable arrest · Not effective if &gt;15 min after EMS arrival", BODY))
ca_story.append(Paragraph("→ ET route no longer recommended (poor absorption)", BODY))
ca_story.append(Spacer(1, 2*mm))

# Bradycardia infusion
ca_story.append(Paragraph("BRADYCARDIA INFUSION (haemodynamically unstable, atropine failed):", H2))
brady_data = [
    [Paragraph("Preparation", TBL_HDR), Paragraph("Start Rate", TBL_HDR), Paragraph("Titration", TBL_HDR)],
    [Paragraph("1 mg in 500 mL NS", TBL_CELL_B), Paragraph("2–10 mcg/min", TBL_CELL_B), Paragraph("↑ every 3–5 min\nto effect", TBL_CELL)],
]
brady_tbl = Table(brady_data, colWidths=[36*mm, 28*mm, None])
brady_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), BLUE),
    ("BACKGROUND",    (0,1), (-1,1), LIGHT_BLUE),
    ("BOX",           (0,0), (-1,-1), 0.5, MID_GREY),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 2),
    ("BOTTOMPADDING", (0,0), (-1,-1), 2),
    ("LEFTPADDING",   (0,0), (-1,-1), 3),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
ca_story.append(brady_tbl)
ca_story.append(Spacer(1, 2*mm))

# Shock infusion
ca_story.append(Paragraph("SEPTIC/CARDIOGENIC SHOCK INFUSION:", H2))
shock_data = [
    [Paragraph("Dose Range", TBL_HDR), Paragraph("Predominant Effect", TBL_HDR)],
    [Paragraph("0.01–0.1 mcg/kg/min", TBL_CELL_B), Paragraph("β predominant → inotropy, chronotropy", TBL_CELL)],
    [Paragraph("0.1–1 mcg/kg/min", TBL_CELL_B), Paragraph("α predominant → vasoconstriction, ↑ SVR", TBL_CELL)],
]
shock_tbl = Table(shock_data, colWidths=[40*mm, None])
shock_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), BLUE),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [LIGHT_BLUE, LIGHT_GREY]),
    ("BOX",           (0,0), (-1,-1), 0.5, MID_GREY),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 2),
    ("BOTTOMPADDING", (0,0), (-1,-1), 2),
    ("LEFTPADDING",   (0,0), (-1,-1), 3),
    ("RIGHTPADDING",  (0,0), (-1,-1), 3),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
ca_story.append(shock_tbl)

# Build right column as nested table
right_inner = Table([[x] for x in ca_story], colWidths=[col_w])
right_inner.setStyle(TableStyle([
    ("TOPPADDING", (0,0), (-1,-1), 0),
    ("BOTTOMPADDING", (0,0), (-1,-1), 1),
    ("LEFTPADDING", (0,0), (-1,-1), 0),
    ("RIGHTPADDING", (0,0), (-1,-1), 0),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))

# Two-column main table
main_cols = Table([[left_inner, Spacer(3*mm, 1), right_inner]],
                  colWidths=[col_w, 3*mm, col_w])
main_cols.setStyle(TableStyle([
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ("TOPPADDING",    (0,0), (-1,-1), 0),
    ("BOTTOMPADDING", (0,0), (-1,-1), 0),
    ("LEFTPADDING",   (0,0), (-1,-1), 0),
    ("RIGHTPADDING",  (0,0), (-1,-1), 0),
]))
story.append(main_cols)
story.append(Spacer(1, 3*mm))

# ═══════════════════════════════════════════════════════════════════════════
# MECHANISM SUMMARY BAR
# ═══════════════════════════════════════════════════════════════════════════
story.append(section_bar("MECHANISM OF ACTION — RECEPTOR SUMMARY", bg=DARK_GREY))
story.append(Spacer(1, 1.5*mm))

moa_data = [
    [Paragraph("Receptor", TBL_HDR), Paragraph("Location", TBL_HDR),
     Paragraph("Effect", TBL_HDR), Paragraph("Clinical Benefit", TBL_HDR)],
    [Paragraph("α₁", TBL_CELL_B), Paragraph("Vascular SM", TBL_CELL),
     Paragraph("Vasoconstriction ↑ SVR", TBL_CELL),
     Paragraph("↑ BP · ↓ Angioedema · ↑ Coronary/cerebral perfusion pressure", TBL_CELL)],
    [Paragraph("β₁", TBL_CELL_B), Paragraph("Heart", TBL_CELL),
     Paragraph("↑ HR · ↑ Contractility · ↑ AV conduction", TBL_CELL),
     Paragraph("↑ Cardiac output · Restores rhythm · Treats bradycardia", TBL_CELL)],
    [Paragraph("β₂", TBL_CELL_B), Paragraph("Bronchi · Mast cells", TBL_CELL),
     Paragraph("Bronchodilation · Inhibits degranulation · Vasodilation", TBL_CELL),
     Paragraph("Reverses bronchospasm · Stops mediator release in anaphylaxis", TBL_CELL)],
    [Paragraph("Signal\nPath", TBL_CELL_B), Paragraph("β-receptor → Gs protein", TBL_CELL),
     Paragraph("→ Adenylyl cyclase → cAMP → PKA → Ca²⁺ handling", TBL_CELL),
     Paragraph("↑ Rate of contraction · ↑ Peak force · ↑ Rate of relaxation (lusitropy)", TBL_CELL)],
]
moa_tbl = Table(moa_data, colWidths=[16*mm, 32*mm, 56*mm, None])
moa_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), DARK_GREY),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [LIGHT_GREY, WHITE, LIGHT_GREY, WHITE]),
    ("BOX",           (0,0), (-1,-1), 0.5, MID_GREY),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 2),
    ("BOTTOMPADDING", (0,0), (-1,-1), 2),
    ("LEFTPADDING",   (0,0), (-1,-1), 4),
    ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
story.append(moa_tbl)
story.append(Spacer(1, 3*mm))

# ═══════════════════════════════════════════════════════════════════════════
# ADVERSE EFFECTS + CAUTIONS (bottom row, 3 columns)
# ═══════════════════════════════════════════════════════════════════════════
story.append(section_bar("ADVERSE EFFECTS · CAUTIONS · DISCHARGE PLANNING", bg=AMBER))
story.append(Spacer(1, 1.5*mm))

col3 = (W - 28*mm - 4*mm) / 3

# Adverse effects
ae_header = Table([[Paragraph("⚠ ADVERSE EFFECTS", S("tmp", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_LEFT))]],
                  colWidths=[col3])
ae_header.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1), AMBER),
    ("LEFTPADDING",(0,0),(-1,-1),4),("TOPPADDING",(0,0),(-1,-1),3),("BOTTOMPADDING",(0,0),(-1,-1),3)]))
ae_items = [
    "Tachycardia (most common)",
    "Hypertension → stroke / pulm. oedema",
    "Ventricular ectopy / VT (high dose)",
    "Myocardial ischaemia (↑ O₂ demand)",
    "Pulmonary shunting",
    "Cerebral vasoconstriction (post-arrest)",
    "Hyperglycaemia",
    "Tissue necrosis (extravasation)",
]
ae_data = [[Paragraph(f"• {i}", TBL_CELL)] for i in ae_items]
ae_tbl = Table(ae_data, colWidths=[col3 - 2*mm])
ae_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), LIGHT_AMBER),
    ("BOX",           (0,0), (-1,-1), 0.5, AMBER),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 1.5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 1.5),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
]))

# Cautions
caut_header = Table([[Paragraph("🔶 CAUTIONS / SPECIAL CASES", S("tmp", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_LEFT))]],
                    colWidths=[col3])
caut_header.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1), AMBER),
    ("LEFTPADDING",(0,0),(-1,-1),4),("TOPPADDING",(0,0),(-1,-1),3),("BOTTOMPADDING",(0,0),(-1,-1),3)]))
cauts = [
    ("Anaphylaxis", "NO absolute contraindications — always give"),
    ("β-Blockers", "Add glucagon 1–2 mg IV; α effects may ↑"),
    ("Cardiac arrest", "No absolute contraindications"),
    ("Alkaline solutions", "DO NOT MIX — inactivated"),
    ("CAD / hypertension", "Caution with infusions; ↑ ischaemia risk"),
    ("Extravasation", "Phentolamine local infiltration"),
    ("Hyperthyroidism", "Enhanced sensitivity; reduce dose"),
    ("Phaeochromocytoma", "Relative CI — hypertensive crisis risk"),
]
caut_data = [[Paragraph(f"<b>{c[0]}:</b> {c[1]}", TBL_CELL)] for c in cauts]
caut_tbl = Table(caut_data, colWidths=[col3 - 2*mm])
caut_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), LIGHT_AMBER),
    ("BOX",           (0,0), (-1,-1), 0.5, AMBER),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 1.5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 1.5),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
]))

# Discharge planning
disc_header = Table([[Paragraph("✅ DISCHARGE (Anaphylaxis)", S("tmp", fontSize=9, fontName="Helvetica-Bold", textColor=WHITE, alignment=TA_LEFT))]],
                    colWidths=[col3])
disc_header.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1), GREEN),
    ("LEFTPADDING",(0,0),(-1,-1),4),("TOPPADDING",(0,0),(-1,-1),3),("BOTTOMPADDING",(0,0),(-1,-1),3)]))
disc_items = [
    "Observe ≥ 4–6 h (8–12 h if severe)",
    "Prescribe ≥ 2 EpiPen autoinjectors",
    "Antihistamine (diphenhydramine 25–50 mg PO q6–8h × 3–5 d)",
    "Prednisolone 40–60 mg/day × 3–5 d",
    "Written anaphylaxis action plan",
    "MedicAlert bracelet advice",
    "Avoid known allergen — education",
    "Allergy/immunology referral if severe/recurrent",
    "Switch β-blocker if patient on one",
]
disc_data = [[Paragraph(f"• {i}", TBL_CELL)] for i in disc_items]
disc_tbl = Table(disc_data, colWidths=[col3 - 2*mm])
disc_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), LIGHT_GREEN),
    ("BOX",           (0,0), (-1,-1), 0.5, GREEN),
    ("INNERGRID",     (0,0), (-1,-1), 0.3, MID_GREY),
    ("TOPPADDING",    (0,0), (-1,-1), 1.5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 1.5),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
]))

# 3-column layout
def build_col(header, tbl):
    inner = Table([[header],[tbl]], colWidths=[col3])
    inner.setStyle(TableStyle([
        ("TOPPADDING",    (0,0), (-1,-1), 0),
        ("BOTTOMPADDING", (0,0), (-1,-1), 0),
        ("LEFTPADDING",   (0,0), (-1,-1), 0),
        ("RIGHTPADDING",  (0,0), (-1,-1), 0),
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ]))
    return inner

bottom_row = Table([[build_col(ae_header, ae_tbl),
                     Spacer(2*mm, 1),
                     build_col(caut_header, caut_tbl),
                     Spacer(2*mm, 1),
                     build_col(disc_header, disc_tbl)]],
                   colWidths=[col3, 2*mm, col3, 2*mm, col3])
bottom_row.setStyle(TableStyle([
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ("TOPPADDING",    (0,0), (-1,-1), 0),
    ("BOTTOMPADDING", (0,0), (-1,-1), 0),
    ("LEFTPADDING",   (0,0), (-1,-1), 0),
    ("RIGHTPADDING",  (0,0), (-1,-1), 0),
]))
story.append(bottom_row)
story.append(Spacer(1, 3*mm))

# ═══════════════════════════════════════════════════════════════════════════
# FOOTER
# ═══════════════════════════════════════════════════════════════════════════
HRFlowable(width="100%", thickness=0.5, color=MID_GREY)
footer_data = [[
    Paragraph(
        "Sources: Tintinalli's Emergency Medicine 9e · Miller's Anesthesia 10e · Harrison's Principles 22e · Roberts &amp; Hedges' Clinical Procedures in Emergency Medicine · ACLS/PALS Guidelines",
        FOOTER),
    Paragraph(
        "For trained healthcare professionals only. Verify all doses and concentrations independently before administration. Not a substitute for clinical judgment.",
        S("FR", fontSize=6.5, fontName="Helvetica-Oblique", textColor=MID_GREY, alignment=TA_RIGHT))
]]
footer_tbl = Table(footer_data, colWidths=[(W-28*mm)*0.55, (W-28*mm)*0.45])
footer_tbl.setStyle(TableStyle([
    ("TOPPADDING",    (0,0), (-1,-1), 3),
    ("BOTTOMPADDING", (0,0), (-1,-1), 0),
    ("LEFTPADDING",   (0,0), (-1,-1), 0),
    ("RIGHTPADDING",  (0,0), (-1,-1), 0),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ("LINEABOVE",     (0,0), (-1,0), 0.5, MID_GREY),
]))
story.append(footer_tbl)

# ── Build ────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF written to: {out_path}")
Your credits are exhausted. Your daily credits reset tomorrow, or you can purchase a top-up for more.

Create a comparison poster: Anaphylaxis vs Vasovagal Syncope mimickers

Your credits are exhausted. Your daily credits reset tomorrow, or you can purchase a top-up for more.
This is a shared conversation. Sign in to Orris to start your own chat.