Simplify asthma from fishman textbook and Gina 2026 with easy understanding way and also explain clinician point of view what should we do in opd for asthma patients during diagnosis treatment

Reading File
Finding Sources
Searching the Web

GINA 2026 asthma guidelines diagnosis treatment updates

Searching PubMed

asthma diagnosis management guidelines 2025 2026

Reading File
Reading Web Page

https://www.guidelinecentral.com/insights/may-2026-gina-asth…

Finding Sources
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Here is your complete, simplified guide to asthma - combining Murray & Nadel's Textbook of Respiratory Medicine (the respiratory medicine equivalent of Fishman's) with GINA 2026, written for clinical OPD use.

ASTHMA - Simplified Clinical Guide

Murray & Nadel's Respiratory Medicine + GINA 2026


1. WHAT IS ASTHMA? (Simple Understanding)

Think of asthma as "angry airways" that:
  1. Inflame (inside walls swell up)
  2. Constrict (muscle around airways squeezes)
  3. Clog (mucus fills the tube)
The result: air goes in but struggles to come out → wheeze, cough, chest tightness, breathlessness
The key feature is that this obstruction is mostly reversible - the airways can open up again (with treatment or spontaneously). This is what separates asthma from COPD.
"Asthma is characterized by airway inflammation leading to mostly reversible airways obstruction. Chronic inflammation, angiogenesis, subepithelial fibrosis, and extracellular matrix deposition are often features of the disease."
  • Murray & Nadel's Textbook of Respiratory Medicine

2. WHAT CAUSES IT? (Pathophysiology - Made Easy)

The 3-Layer Problem:

LayerWhat HappensSimple Analogy
Airway wallInflammation, edema, subepithelial fibrosisWall of a pipe swelling inward
Smooth muscleContracts due to triggersPipe squeezing shut
LumenMucus pluggingPipe getting blocked with goo

Who Gets It?

  • Genetic component: Genes near IL-1RL1, TSLP, IL-33 - all involved in type 2 T-helper immune responses and allergic dysregulation of the epithelial barrier
  • 17q21 locus (ORMDL3 gene) - found in first asthma genome-wide studies; regulates sphingolipid synthesis
  • Environmental triggers: allergens (dust mites, pollen, cockroach, pet dander), cold air, exercise, smoke, infections, stress, NSAIDs, aspirin, beta-blockers

Key Immune Mechanism:

  • Type 2 inflammation is the dominant pathway: IgE-mediated mast cell activation → eosinophil recruitment → IL-4, IL-5, IL-13 release → airway remodeling
  • Airway hyperresponsiveness (AHR): the airways are "twitchy" - they constrict to stimuli that don't affect normal airways

3. SYMPTOMS & SIGNS (What to Look For)

Classic Quartet:

  1. Wheeze (high-pitched, usually expiratory)
  2. Cough (especially at night or early morning)
  3. Chest tightness
  4. Breathlessness (especially with exercise)

Classic Pattern Clues:

  • Symptoms vary over time and in intensity
  • Worse at night or early morning
  • Triggered by exercise, cold air, smoke, allergens
  • Better with bronchodilators
  • Often associated with eczema, allergic rhinitis, family history

4. DIAGNOSIS - OPD Practical Steps (Clinician's Checklist)

Step 1: Take a Focused History

Ask these questions:
  • "Do you wheeze?" / "Do you wake up coughing at night?"
  • "Do symptoms improve with a puffer (inhaler)?"
  • "Any triggers - exercise, dust, smoke, cold?"
  • "Do you or family have eczema, hay fever, allergies?"
  • "Any aspirin/NSAIDs use causing breathing issues?"
  • "Occupation?" (baker, painter, nurse - occupational asthma)

Step 2: Physical Examination in OPD

  • Check respiratory rate, SpO2
  • Look for nasal polyps, eczema (atopic triad)
  • Chest: wheeze on forced expiration (may be absent if mild/in remission)
  • Check for accessory muscle use (if severe)

Step 3: Confirm with Spirometry (Most Important!)

GINA 2026 requires objective evidence of variable airflow limitation:
TestPositive If...Meaning
FEV1/FVC ratio< 0.70 (or below lower limit of normal)Obstruction present
Bronchodilator reversibilityFEV1 increases ≥12% AND ≥200 mL after salbutamol 400 mcgConfirms reversible obstruction
Peak flow variability>10% diurnal variation on ≥2 days/week for 2 weeksSupports asthma
Methacholine challenge (PC20)PC20 ≤8 mg/mLConfirms airway hyperresponsiveness
Exercise testFEV1 falls ≥10% after exerciseExercise-induced asthma
OPD Tip: If spirometry is normal but history is strong, do methacholine challenge or give a trial of ICS for 4-6 weeks and reassess spirometry.
GINA 2026 says: Diagnosis MUST be confirmed with objective evidence before starting regular treatment - don't diagnose on symptoms alone.

Step 4: Assess Severity/Control

GINA uses "Level of Asthma Control":
FeatureWell ControlledPartly ControlledUncontrolled
Daytime symptoms≤2 days/week>2 days/week≥3 of these features
Night wakingNoneAny
Reliever use≤2 days/week>2 days/week
Activity limitationNoneAny
Also assess exacerbation risk - ask about:
  • Previous ICU admissions / intubations (HIGH RISK - flag them!)
  • ≥1 severe exacerbation in past year
  • Low FEV1 (<60% predicted)
  • High SABA use (>1 canister/month)
  • Current smoker
  • Non-adherence to ICS

Step 5: Identify Treatable Traits / Comorbidities

In every OPD visit, screen for:
  • Allergic rhinitis (treat it - it makes asthma worse)
  • GERD (acid reflux triggers asthma)
  • Obesity (worsens asthma control)
  • Nasal polyps (may indicate NSAID-exacerbated respiratory disease)
  • Anxiety/depression (poor adherence)
  • Obstructive sleep apnea

5. TREATMENT - GINA 2026 Step Approach

The Big Rule Change (GINA 2019 onwards, confirmed 2026):

SABA (salbutamol) alone is NO LONGER recommended at any step. Every asthma patient must receive ICS-containing therapy.
Why? SABA alone masks inflammation without treating it. Over-reliance on SABA increases risk of fatal attacks.

TWO TREATMENT TRACKS:

Track 1 (Preferred): ICS-Formoterol as both reliever AND controller (MART)
  • Uses a single ICS-formoterol inhaler for everything
  • Patient uses it both regularly AND as needed for symptoms
Track 2 (Alternative): ICS-SABA anti-inflammatory reliever (AIR) - NEW in GINA 2026 Step 1
  • For patients who cannot access or tolerate ICS-formoterol
  • Low-dose ICS + SABA combined as reliever

GINA 2026 TREATMENT STEPS (Adults & Adolescents):

StepPreferred ControllerPreferred RelieverNotes
Step 1 (mild, intermittent)As-needed low-dose ICS-formoterolICS-formoterolNEW: ICS-SABA (AIR) also option at Step 1
Step 2 (mild, persistent)Low-dose ICS daily + as-needed ICS-formoterolICS-formoterol
Step 3 (moderate)Low-dose ICS-formoterol (MART)ICS-formoterol
Step 4 (uncontrolled)Medium-dose ICS-formoterol (MART)ICS-formoterolConsider LAMA add-on
Step 5 (severe)High-dose ICS + LABA + specialist reviewICS-formoterolAdd LAMA (tiotropium), consider biologics

GINA 2026 BIOLOGICS (Step 5) - Severe Asthma:

Biologic therapy is for patients with severe, uncontrolled asthma despite step 4/5 treatment:
DrugTargetWho Gets It
OmalizumabAnti-IgEAllergic asthma, high IgE, sensitized allergens
Mepolizumab / Benralizumab / ReslizumabAnti-IL-5 / Anti-IL-5REosinophilic asthma (blood eos ≥150-300)
DupilumabAnti-IL-4/IL-13 (IL-4Rα)Type 2 asthma, also works in CRS/eczema
TezepelumabAnti-TSLPBroadest - works in type 2 and non-type 2
DepemokimabAnti-IL-5 (long-acting)NEW in GINA 2026 - dosing every 6 months
GINA 2026 update: Depemokimab (ultra-long-acting anti-IL-5) and omalizumab biosimilar are now incorporated.

KEY GINA 2026 UPDATES (What's New):

  1. ICS-SABA (AIR) added at Step 1 - gives a SABA-free alternative for patients who can't use formoterol
  2. 4 new OPD/ED flowcharts for acute exacerbations (adults, adolescents, children 6-11, children ≤5)
  3. Oxygen revised: Give O2 ONLY if SpO2 <92%; target SpO2 92-95% (not >95% - oxygen toxicity risk)
  4. ICS-formoterol as mild exacerbation reliever - now formally included as alternative to SABA in ED/primary care
  5. Minimize oral corticosteroids (OCS): treat modifiable risk factors first; OCS is last resort due to systemic effects
  6. Triple therapy (ICS+LABA+LAMA) - budesonide-formoterol-glycopyrronium now added alongside fluticasone-based triple options at Step 5
  7. Anaphylaxis + asthma: Give epinephrine FIRST, then bronchodilators
  8. Shake salbutamol inhaler before each actuation - prevents accidental ultra-high doses (new safety note)

6. OPD CONSULTATION WORKFLOW - Practical Clinician Guide

First Visit (New Patient):

1. History (10 min)
   ├── Symptom pattern (wheeze/cough/breathlessness/chest tightness)
   ├── Triggers (allergens, exercise, cold, ASA, occupational)
   ├── Atopic history (eczema, rhinitis, family history)
   ├── Previous diagnoses, hospitalizations, ICU admissions
   └── Current medications (beta-blockers? NSAIDs?)

2. Examination
   ├── Vitals: RR, SpO2, HR
   ├── Nose: polyps, rhinitis
   └── Chest: wheeze, air entry

3. Investigations
   ├── Spirometry with bronchodilator reversibility test [MANDATORY]
   ├── Peak expiratory flow (PEF) diary for 2 weeks
   ├── Chest X-ray (to exclude other diagnoses)
   ├── CBC (eosinophilia?)
   ├── Total IgE, skin prick test or specific IgE (if allergic asthma suspected)
   └── FeNO (fractional exhaled nitric oxide) - if available, >25 ppb suggests type 2 inflammation

4. Confirm Diagnosis
   └── Objective evidence of variable airflow limitation (GINA requirement)

5. Assess Control + Risk
   └── GINA control table (see above)

6. Start Treatment
   ├── Prescribe appropriate GINA step
   ├── Prescribe one inhaler device type (minimize switching)
   ├── Demonstrate inhaler technique (most common reason for failure!)
   └── Give written Asthma Action Plan

7. Education
   ├── Explain triggers and how to avoid
   ├── When to go to hospital (SpO2 <92%, can't speak full sentences)
   └── No SABA-only use

Follow-Up Visit (Established Patient):

Ask every visit:
├── How many times have you used your reliever this week?
├── Any night waking?
├── Any activity limitation?
├── Any exacerbations / ED visits / oral steroids?
├── Any missed doses?
└── Show me how you use your inhaler

Do every visit:
├── Check SpO2, peak flow (if available)
├── Review compliance and technique
└── Step up or down based on control assessment

Step up if: Uncontrolled for ≥1 month
Step down if: Well controlled for ≥3 months (try reducing dose by 25-50%)

7. ACUTE EXACERBATION IN OPD - GINA 2026 Protocol

Severity Assessment:

FeatureMildModerateSevereLife-Threatening
SpeaksSentencesPhrasesWords onlyMute
Resp RateNormal20-30/min>30/min>30/min
SpO2≥95%92-95%<92%<92%
PEF (% predicted)>70%40-69%<40%<25%
WheezeModerateLoudLoudSilent (no air entry)

Immediate Management (OPD/Primary Care):

Mild Exacerbation:
  • ICS-formoterol (as-needed) OR salbutamol 4-10 puffs via spacer every 20 min x 3 (shake before each puff!)
  • If no improvement in 1 hour → refer to ED
Moderate-Severe Exacerbation:
  • Salbutamol 4-10 puffs via spacer OR nebulizer
  • O2 ONLY if SpO2 <92% → target 92-95%
  • Ipratropium bromide (anticholinergic) add-on if severe
  • Prednisolone 40-50 mg orally (or IV methylprednisolone if unable to swallow)
  • Reassess every 20 minutes
  • Transfer to hospital if no improvement
If Anaphylaxis + Asthma (NEW GINA 2026):
  • Give IM epinephrine FIRST (0.5 mg IM in adults)
  • THEN give bronchodilator
  • Do NOT delay epinephrine for bronchodilator

Red Flags - Refer/Admit Immediately:

  • Previous ICU admission or intubation
  • SpO2 <92% not responding to treatment
  • Silent chest (no wheeze = no air entry)
  • Cyanosis
  • PEF <33% predicted
  • Altered consciousness

8. SPECIAL SITUATIONS

Asthma in Pregnancy:

  • Affects 4-8% of pregnancies
  • Poorly controlled asthma → preeclampsia, preterm birth, low birth weight, intrauterine growth restriction, perinatal death
  • ICS is SAFE in pregnancy - budesonide is preferred (most data)
  • The risks of poorly controlled asthma FAR outweigh drug risks
  • Monitor with spirometry; consider home peak flow
  • Salbutamol: safe; LABA: use with ICS only; OCS: use if needed (benefit > risk)
(Murray & Nadel's Textbook of Respiratory Medicine)

Occupational Asthma:

  • Suspect if: symptoms improve on weekends/holidays, new-onset in adult, specific occupational exposure
  • Work-up: serial PEF measurements at work vs. rest days
  • Treatment: REMOVE from exposure (most important step)
  • ATS recommends reassessment ≥2 years after removal from exposure before final impairment rating

9. INHALER TECHNIQUE - THE MOST OVERLOOKED STEP

GINA 2026 emphasizes: Check inhaler technique at every visit.
"Inhaler technique is still the most common reason for treatment failure. Before escalating a patient, watch them use their device."
Practical tips:
  • Use ONE device type per patient where possible
  • Prescribe spacer with MDI (metered dose inhaler) for all patients
  • In OPD, have the patient demonstrate their technique - errors are almost universal
  • Key errors: not coordinating actuation with inhalation, not holding breath for 10 seconds, not shaking MDI before use

10. QUICK REFERENCE CARD (Tear-Out for OPD)

DIAGNOSIS CHECKLIST:
☐ Variable symptoms (wheeze, cough, breathlessness, chest tightness)
☐ Spirometry: FEV1/FVC < 0.70
☐ Bronchodilator test: FEV1 rise ≥12% AND ≥200 mL
☐ Exclude other causes (CXR, CBC)

EVERY OPD VISIT:
☐ Reliever use this week? (>2x/week = uncontrolled)
☐ Night symptoms?
☐ Activity limitation?
☐ Exacerbations?
☐ CHECK INHALER TECHNIQUE

TREATMENT RULES (GINA 2026):
☐ No SABA alone - ever
☐ All patients need ICS
☐ Prefer ICS-formoterol as both reliever + controller
☐ Step up if uncontrolled ≥1 month
☐ Step down if controlled ≥3 months
☐ O2 only if SpO2 <92%

REFER TO SPECIALIST IF:
☐ Diagnosis uncertain
☐ Poor control despite step 3-4
☐ Suspected severe asthma / biologics candidate
☐ Occupational asthma
☐ Frequent exacerbations (≥2 severe/year)

Sources:

Generate a clinical decision flowchart PDF for OPD asthma diagnosis and management

Reading File
Running Command

mkdir -p /home/daytona/workspace/asthma-flowchart && ls /home/daytona/workspace/asthma-flowchart

Writing File

~/asthma-flowchart/generate_flowchart.py

"""
OPD Asthma Clinical Decision Flowchart - GINA 2026
Generates a multi-page A4 PDF with colour-coded flowcharts
"""

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.pdfgen import canvas
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import Paragraph
from reportlab.lib.enums import TA_CENTER, TA_LEFT

W, H = A4  # 595 x 842 pt

# ── Colour palette ────────────────────────────────────────────────────────────
NAVY    = colors.HexColor("#1a3a5c")
BLUE    = colors.HexColor("#1e6fa8")
LTBLUE  = colors.HexColor("#d6eaf8")
GREEN   = colors.HexColor("#1a7a4a")
LTGREEN = colors.HexColor("#d5f5e3")
AMBER   = colors.HexColor("#c07000")
LTAMB   = colors.HexColor("#fef3cd")
RED     = colors.HexColor("#b22222")
LTRED   = colors.HexColor("#fde8e8")
PURPLE  = colors.HexColor("#6a0dad")
LTPUR   = colors.HexColor("#f0e6ff")
GREY    = colors.HexColor("#555555")
LTGREY  = colors.HexColor("#f4f6f7")
WHITE   = colors.white
ORANGE  = colors.HexColor("#e07b00")
LTORA   = colors.HexColor("#fff3e0")

# ── Helper drawing functions ──────────────────────────────────────────────────

def page_header(c, title, subtitle="", page_num=1, total_pages=4):
    """Draw a professional header bar."""
    c.setFillColor(NAVY)
    c.rect(0, H - 38*mm, W, 38*mm, fill=1, stroke=0)
    c.setFillColor(WHITE)
    c.setFont("Helvetica-Bold", 16)
    c.drawString(12*mm, H - 18*mm, "OPD ASTHMA CLINICAL DECISION FLOWCHART")
    c.setFont("Helvetica", 10)
    c.drawString(12*mm, H - 27*mm, title)
    c.setFont("Helvetica-Oblique", 8)
    c.drawRightString(W - 12*mm, H - 27*mm, f"GINA 2026  |  Page {page_num}/{total_pages}")
    if subtitle:
        c.setFont("Helvetica", 8)
        c.drawString(12*mm, H - 34*mm, subtitle)

def page_footer(c, note=""):
    """Draw footer."""
    c.setFillColor(NAVY)
    c.rect(0, 0, W, 10*mm, fill=1, stroke=0)
    c.setFillColor(WHITE)
    c.setFont("Helvetica-Oblique", 7)
    txt = note if note else "Based on GINA 2026 Strategy Report & Murray-Nadel's Textbook of Respiratory Medicine  |  For clinical use"
    c.drawCentredString(W/2, 3.5*mm, txt)

def box(c, x, y, w, h, fill_col, border_col=None, radius=4):
    """Rounded rectangle."""
    if border_col is None:
        border_col = fill_col
    c.setFillColor(fill_col)
    c.setStrokeColor(border_col)
    c.setLineWidth(1.2)
    c.roundRect(x, y, w, h, radius, fill=1, stroke=1)

def diamond(c, cx, cy, hw, hh, fill_col, border_col=None):
    """Decision diamond."""
    if border_col is None:
        border_col = fill_col
    p = c.beginPath()
    p.moveTo(cx, cy + hh)
    p.lineTo(cx + hw, cy)
    p.lineTo(cx, cy - hh)
    p.lineTo(cx - hw, cy)
    p.closePath()
    c.setFillColor(fill_col)
    c.setStrokeColor(border_col)
    c.setLineWidth(1.2)
    c.drawPath(p, fill=1, stroke=1)

def label(c, x, y, w, text, font="Helvetica", size=8, color=colors.black,
          align="center", bold=False):
    """Multi-line text inside a box - auto-wraps."""
    font_name = "Helvetica-Bold" if bold else font
    c.setFont(font_name, size)
    c.setFillColor(color)
    # Split into lines manually
    words = text.split(" ")
    lines = []
    current = ""
    max_chars = int(w / (size * 0.55))
    for word in words:
        test = (current + " " + word).strip()
        if len(test) <= max_chars:
            current = test
        else:
            if current:
                lines.append(current)
            current = word
    if current:
        lines.append(current)
    line_h = size * 1.4
    total_h = len(lines) * line_h
    start_y = y + total_h / 2 - line_h * 0.3
    for i, line in enumerate(lines):
        ly = start_y - i * line_h
        if align == "center":
            c.drawCentredString(x + w/2, ly, line)
        elif align == "left":
            c.drawString(x + 3, ly, line)

def arrow(c, x1, y1, x2, y2, label_text="", color=GREY, lbl_color=None):
    """Arrow with optional label."""
    c.setStrokeColor(color)
    c.setLineWidth(1.2)
    c.line(x1, y1, x2, y2)
    # Arrowhead
    import math
    angle = math.atan2(y2 - y1, x2 - x1)
    aw = 5
    c.setFillColor(color)
    p = c.beginPath()
    p.moveTo(x2, y2)
    p.lineTo(x2 - aw * math.cos(angle - 0.4), y2 - aw * math.sin(angle - 0.4))
    p.lineTo(x2 - aw * math.cos(angle + 0.4), y2 - aw * math.sin(angle + 0.4))
    p.closePath()
    c.drawPath(p, fill=1, stroke=0)
    if label_text:
        mx, my = (x1+x2)/2, (y1+y2)/2
        c.setFont("Helvetica-Bold", 7.5)
        c.setFillColor(lbl_color if lbl_color else color)
        c.drawCentredString(mx, my + 4, label_text)

def section_title(c, x, y, text, color=NAVY):
    c.setFont("Helvetica-Bold", 10)
    c.setFillColor(color)
    c.drawString(x, y, text)
    c.setStrokeColor(color)
    c.setLineWidth(1)
    c.line(x, y - 2, x + 170*mm, y - 2)


# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 1 – DIAGNOSIS FLOWCHART
# ═══════════════════════════════════════════════════════════════════════════════

def page1_diagnosis(c):
    c.setPageSize(A4)
    page_header(c, "PAGE 1 — DIAGNOSIS ALGORITHM", "Step-by-step approach for new OPD patient", 1, 4)
    page_footer(c)

    TOP = H - 45*mm
    BW = 130*mm   # box width
    BH = 11*mm    # box height
    CX = W/2      # centre x
    BX = CX - BW/2

    # ── Step 1: Presenting symptoms ──────────────────────────────────────────
    box(c, BX, TOP - BH, BW, BH, LTBLUE, BLUE)
    label(c, BX, TOP - BH, BW, "PATIENT PRESENTS WITH RESPIRATORY SYMPTOMS",
          bold=True, size=9, color=NAVY)
    arrow(c, CX, TOP - BH, CX, TOP - BH - 7*mm, color=BLUE)

    # Symptoms list box
    sy = TOP - BH - 7*mm - 24*mm
    box(c, BX, sy, BW, 24*mm, LTBLUE, BLUE)
    c.setFont("Helvetica-Bold", 8.5)
    c.setFillColor(NAVY)
    c.drawString(BX + 3*mm, sy + 19*mm, "Classic Symptom Quartet (ask ALL 4):")
    c.setFont("Helvetica", 8)
    c.setFillColor(colors.black)
    items = ["1. Wheeze  (expiratory, high-pitched)",
             "2. Cough  (worse at night / early morning)",
             "3. Chest tightness",
             "4. Breathlessness  (especially on exertion)"]
    for i, item in enumerate(items):
        c.drawString(BX + 5*mm, sy + 14*mm - i*4.5*mm, item)

    arrow(c, CX, sy, CX, sy - 7*mm, color=BLUE)

    # ── Diamond 1: Variable symptoms? ────────────────────────────────────────
    d1y = sy - 7*mm - 12*mm
    diamond(c, CX, d1y, 52*mm, 12*mm, LTAMB, AMBER)
    c.setFont("Helvetica-Bold", 8)
    c.setFillColor(AMBER)
    c.drawCentredString(CX, d1y + 3, "Are symptoms VARIABLE over time &")
    c.drawCentredString(CX, d1y - 5, "do they worsen with known triggers?")

    # NO branch (right)
    arrow(c, CX + 52*mm, d1y, CX + 68*mm, d1y, color=RED, label_text="NO")
    box(c, CX + 68*mm, d1y - 7*mm, 40*mm, 14*mm, LTRED, RED)
    label(c, CX + 68*mm, d1y - 7*mm, 40*mm,
          "Consider alternative diagnosis (COPD, VCD, HF, PE)",
          size=7, color=RED, bold=True)

    # YES branch (down)
    arrow(c, CX, d1y - 12*mm, CX, d1y - 12*mm - 7*mm, color=GREEN, label_text="YES")

    # ── Spirometry block ─────────────────────────────────────────────────────
    spy = d1y - 12*mm - 7*mm - 18*mm
    box(c, BX, spy, BW, 18*mm, LTGREEN, GREEN)
    c.setFont("Helvetica-Bold", 9)
    c.setFillColor(GREEN)
    c.drawString(BX + 3*mm, spy + 13*mm, "ORDER SPIROMETRY + BRONCHODILATOR TEST  (MANDATORY)")
    c.setFont("Helvetica", 8)
    c.setFillColor(colors.black)
    c.drawString(BX + 5*mm, spy + 8.5*mm, "Pre & Post salbutamol 400 mcg (4 puffs) via spacer")
    c.drawString(BX + 5*mm, spy + 4.5*mm, "Measure FEV1, FVC, FEV1/FVC ratio  |  Repeat in 15 min")

    arrow(c, CX, spy, CX, spy - 7*mm, color=BLUE)

    # ── Diamond 2: FEV1/FVC < 0.70? ──────────────────────────────────────────
    d2y = spy - 7*mm - 11*mm
    diamond(c, CX, d2y, 52*mm, 11*mm, LTAMB, AMBER)
    c.setFont("Helvetica-Bold", 8)
    c.setFillColor(AMBER)
    c.drawCentredString(CX, d2y + 2, "FEV1/FVC < 0.70  AND")
    c.drawCentredString(CX, d2y - 5, "FEV1 rises >=12% + >=200mL post-BD?")

    # NO right
    arrow(c, CX + 52*mm, d2y, CX + 68*mm, d2y, color=AMBER, label_text="NO")
    box(c, CX + 68*mm, d2y - 7*mm, 40*mm, 14*mm, LTAMB, AMBER)
    label(c, CX + 68*mm, d2y - 7*mm, 40*mm,
          "Normal spirometry: consider methacholine challenge or 4-6 wk ICS trial",
          size=7, color=AMBER, bold=False)

    # YES down
    arrow(c, CX, d2y - 11*mm, CX, d2y - 11*mm - 7*mm, color=GREEN, label_text="YES")

    # ── Additional workup ─────────────────────────────────────────────────────
    wky = d2y - 11*mm - 7*mm - 22*mm
    box(c, BX, wky, BW, 22*mm, LTGREY, GREY)
    c.setFont("Helvetica-Bold", 8.5)
    c.setFillColor(GREY)
    c.drawString(BX + 3*mm, wky + 17.5*mm, "ADDITIONAL WORKUP in OPD:")
    c.setFont("Helvetica", 8)
    c.setFillColor(colors.black)
    items2 = ["CBC (eosinophilia), Total IgE, Skin prick test / specific IgE",
              "Chest X-ray (exclude other causes)",
              "FeNO (if available) — >25 ppb = type-2 airway inflammation",
              "Peak flow diary: >10% diurnal variation x2 days/week x2 weeks"]
    for i, it in enumerate(items2):
        c.drawString(BX + 5*mm, wky + 13*mm - i*3.8*mm, f"\u2022 {it}")

    arrow(c, CX, wky, CX, wky - 7*mm, color=BLUE)

    # ── CONFIRMED DIAGNOSIS ───────────────────────────────────────────────────
    cdy = wky - 7*mm - 11*mm
    box(c, BX, cdy, BW, 11*mm, GREEN, GREEN)
    label(c, BX, cdy, BW, "ASTHMA CONFIRMED  — Proceed to Severity/Control Assessment (Page 2)",
          bold=True, size=9, color=WHITE)

    # ── Right sidebar: Differentials ─────────────────────────────────────────
    sx = W - 52*mm
    sy2 = TOP - BH - 10*mm
    box(c, sx, sy2 - 70*mm, 43*mm, 70*mm, LTRED, RED)
    c.setFont("Helvetica-Bold", 8)
    c.setFillColor(RED)
    c.drawString(sx + 2*mm, sy2 - 4*mm, "RED FLAG DIFFERENTIALS")
    c.setFont("Helvetica", 7.5)
    c.setFillColor(colors.black)
    diffs = ["COPD (fixed obstruction,\n smoker, age >40)",
             "Vocal cord dysfunction\n (inspiratory stridor)",
             "Heart failure\n (bilateral crackles, BNP)",
             "Pulmonary embolism\n (pleuritic pain, D-dimer)",
             "Bronchiectasis\n (daily productive cough)",
             "Endobronchial tumour\n (unilateral wheeze, haemoptysis)"]
    for i, d in enumerate(diffs):
        lines_ = d.split("\n")
        c.setFont("Helvetica-Bold", 7)
        c.drawString(sx + 3*mm, sy2 - 12*mm - i*11*mm, f"\u2022 {lines_[0]}")
        if len(lines_) > 1:
            c.setFont("Helvetica", 7)
            c.drawString(sx + 5*mm, sy2 - 16*mm - i*11*mm, lines_[1])

    # ── Bottom note ───────────────────────────────────────────────────────────
    c.setFont("Helvetica-Oblique", 7.5)
    c.setFillColor(NAVY)
    c.drawString(12*mm, 12*mm,
        "GINA 2026: Diagnosis MUST be confirmed with objective evidence of variable airflow limitation before starting regular treatment.")

    c.showPage()


# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 2 – SEVERITY / CONTROL & TREATMENT STEPS
# ═══════════════════════════════════════════════════════════════════════════════

def page2_control_treatment(c):
    c.setPageSize(A4)
    page_header(c, "PAGE 2 — CONTROL ASSESSMENT & TREATMENT STEPS",
                "GINA 2026 Step Approach (Adults & Adolescents)", 2, 4)
    page_footer(c)

    y = H - 48*mm

    # ── Section A: Control Assessment Table ──────────────────────────────────
    section_title(c, 12*mm, y, "A. ASSESS ASTHMA CONTROL  (ask at every OPD visit)")
    y -= 8*mm

    col_labels = ["Feature", "Well Controlled", "Partly Controlled", "Uncontrolled"]
    col_w = [50*mm, 38*mm, 38*mm, 38*mm]
    col_x = [12*mm]
    for w_ in col_w[:-1]:
        col_x.append(col_x[-1] + w_)
    row_h = 9*mm
    header_y = y

    # Header row
    for i, (lbl, cx_, cw_) in enumerate(zip(col_labels, col_x, col_w)):
        fc = NAVY if i == 0 else (LTGREEN if i == 1 else (LTAMB if i == 2 else LTRED))
        tc = WHITE if i == 0 else (GREEN if i == 1 else (AMBER if i == 2 else RED))
        box(c, cx_, header_y - row_h, cw_, row_h, fc, NAVY if i == 0 else tc)
        c.setFont("Helvetica-Bold", 8)
        c.setFillColor(tc if i == 0 else tc)
        c.drawCentredString(cx_ + cw_/2, header_y - row_h + 3*mm, lbl)

    # Data rows
    rows = [
        ("Daytime symptoms", "<=2 days/week", ">2 days/week", ">2 days/week"),
        ("Night waking due to asthma", "None", "Any", "Any"),
        ("Reliever use (SABA/ICS-form)", "<=2 days/week", ">2 days/week", ">2 days/week"),
        ("Activity limitation", "None", "Any", "Any"),
        ("Feature count threshold", "0 features", "1-2 features", "3-4 features"),
    ]
    for ri, row in enumerate(rows):
        ry = header_y - (ri + 2) * row_h
        for ci, (cell, cx_, cw_) in enumerate(zip(row, col_x, col_w)):
            fc = LTGREY if ri % 2 == 0 else WHITE
            if ci == 0:
                box(c, cx_, ry, cw_, row_h, LTBLUE, BLUE)
                c.setFont("Helvetica-Bold", 7.5)
                c.setFillColor(NAVY)
            else:
                fc2 = LTGREEN if ci == 1 else (LTAMB if ci == 2 else LTRED)
                box(c, cx_, ry, cw_, row_h, fc2, GREY)
                c.setFont("Helvetica", 7.5)
                c.setFillColor(colors.black)
            c.drawCentredString(cx_ + cw_/2, ry + 3*mm, cell)

    y -= (len(rows) + 2) * row_h + 4*mm

    # ── Section B: Treatment Steps ────────────────────────────────────────────
    section_title(c, 12*mm, y, "B. GINA 2026 TREATMENT STEPS  (ICS = inhaled corticosteroid)")
    y -= 8*mm

    steps = [
        ("STEP 1", "Mild intermittent", LTBLUE, BLUE, NAVY,
         "Track 1: As-needed low-dose ICS-formoterol (preferred)\nTrack 2: As-needed low-dose ICS-SABA  [NEW GINA 2026]",
         "As-needed ICS-formoterol"),
        ("STEP 2", "Mild persistent", LTGREEN, GREEN, GREEN,
         "Track 1: Low-dose ICS daily + as-needed ICS-formoterol\nTrack 2: Low-dose ICS daily + as-needed SABA",
         "As-needed ICS-formoterol"),
        ("STEP 3", "Moderate", LTAMB, AMBER, AMBER,
         "MART: Low-dose ICS-formoterol as both controller AND reliever\n(Maintenance And Reliever Therapy - single inhaler)",
         "As-needed ICS-formoterol"),
        ("STEP 4", "Uncontrolled on Step 3", LTORA, ORANGE, ORANGE,
         "MART: Medium-dose ICS-formoterol  +  Consider add-on LAMA (tiotropium)\nReview diagnosis, adherence, technique before escalating",
         "As-needed ICS-formoterol"),
        ("STEP 5", "Severe / Refractory", LTRED, RED, RED,
         "High-dose ICS-LABA  +  LAMA  +  REFER TO SPECIALIST\nConsider biologics (see Page 4)  |  Minimise oral corticosteroids",
         "As-needed ICS-formoterol"),
    ]

    sw = (W - 24*mm)
    sh = 16*mm
    for i, (step, severity, fc, bc, tc, text, reliever) in enumerate(steps):
        sy3 = y - i * (sh + 1.5*mm)
        box(c, 12*mm, sy3 - sh, sw, sh, fc, bc, radius=5)
        # Step badge
        box(c, 12*mm, sy3 - sh, 22*mm, sh, bc, bc, radius=5)
        c.setFont("Helvetica-Bold", 9)
        c.setFillColor(WHITE)
        c.drawCentredString(23*mm, sy3 - sh/2 - 1.5*mm, step)
        # Severity label
        c.setFont("Helvetica-Bold", 8)
        c.setFillColor(tc)
        c.drawString(36*mm, sy3 - 5*mm, severity)
        # Main text
        lines_ = text.split("\n")
        c.setFont("Helvetica", 7.5)
        c.setFillColor(colors.black)
        for li, line in enumerate(lines_):
            c.drawString(36*mm, sy3 - 9.5*mm - li * 4*mm, line)
        # Reliever badge
        c.setFont("Helvetica-Oblique", 7)
        c.setFillColor(GREY)
        c.drawRightString(W - 14*mm, sy3 - 5*mm, f"Reliever: {reliever}")

    # Step up/down arrows between steps (left margin)
    for i in range(len(steps) - 1):
        ay = y - i * (sh + 1.5*mm) - sh - 0.75*mm
        arrow(c, 7*mm, ay, 7*mm, ay - 1.5*mm + 0.1, color=RED)

    y -= len(steps) * (sh + 1.5*mm) + 4*mm

    # ── Step up / down guidance ───────────────────────────────────────────────
    box(c, 12*mm, y - 12*mm, (W-24*mm)/2 - 2*mm, 12*mm, LTGREEN, GREEN)
    c.setFont("Helvetica-Bold", 8)
    c.setFillColor(GREEN)
    c.drawString(15*mm, y - 5.5*mm, "STEP DOWN if:")
    c.setFont("Helvetica", 7.5)
    c.setFillColor(colors.black)
    c.drawString(15*mm, y - 9.5*mm, "Well controlled for >=3 months  |  Reduce ICS dose by 25-50%")

    box(c, 12*mm + (W-24*mm)/2 + 2*mm, y - 12*mm, (W-24*mm)/2 - 2*mm, 12*mm, LTRED, RED)
    c.setFont("Helvetica-Bold", 8)
    c.setFillColor(RED)
    c.drawString(15*mm + (W-24*mm)/2 + 2*mm, y - 5.5*mm, "STEP UP if:")
    c.setFont("Helvetica", 7.5)
    c.setFillColor(colors.black)
    c.drawString(15*mm + (W-24*mm)/2 + 2*mm, y - 9.5*mm,
                 "Uncontrolled for >=1 month  (check technique & adherence first!)")

    c.showPage()


# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 3 – ACUTE EXACERBATION MANAGEMENT
# ═══════════════════════════════════════════════════════════════════════════════

def page3_acute(c):
    c.setPageSize(A4)
    page_header(c, "PAGE 3 — ACUTE EXACERBATION MANAGEMENT (OPD / PRIMARY CARE)",
                "GINA 2026 Protocol", 3, 4)
    page_footer(c)

    y = H - 48*mm

    # ── Severity table ─────────────────────────────────────────────────────────
    section_title(c, 12*mm, y, "STEP 1 — ASSESS SEVERITY IMMEDIATELY")
    y -= 8*mm

    col_labels2 = ["Feature", "MILD", "MODERATE", "SEVERE", "LIFE-THREATENING"]
    col_w2 = [34*mm, 31*mm, 31*mm, 31*mm, 37*mm]
    col_x2 = [12*mm]
    for w_ in col_w2[:-1]:
        col_x2.append(col_x2[-1] + w_)

    hdr_cols = [NAVY, GREEN, AMBER, ORANGE, RED]
    hdr_txt  = [WHITE, WHITE, WHITE, WHITE, WHITE]
    for i, (lbl, cx_, cw_, hc, ht) in enumerate(zip(col_labels2, col_x2, col_w2, hdr_cols, hdr_txt)):
        box(c, cx_, y - 8*mm, cw_, 8*mm, hc, hc)
        c.setFont("Helvetica-Bold", 7.5)
        c.setFillColor(ht)
        c.drawCentredString(cx_ + cw_/2, y - 5*mm, lbl)

    rows2 = [
        ("Speech", "Full sentences", "Phrases only", "Words only", "Mute / confused"),
        ("SpO2", ">=95%", "92-94%", "<92%", "<90% / cyanosis"),
        ("Resp Rate", "Normal", "20-30/min", ">30/min", "Bradypnoea / gasping"),
        ("PEF (% predicted)", ">70%", "40-69%", "<40%", "<25% / not measurable"),
        ("Wheeze", "Moderate expiratory", "Loud", "Loud", "SILENT CHEST (danger!)"),
        ("Heart Rate", "<100 bpm", "100-120 bpm", ">120 bpm", "Bradycardia"),
    ]
    row_h2 = 8*mm
    for ri, row in enumerate(rows2):
        ry = y - (ri + 2) * row_h2
        for ci, (cell, cx_, cw_) in enumerate(zip(row, col_x2, col_w2)):
            fc = [LTBLUE, LTGREEN, LTAMB, LTORA, LTRED][ci]
            box(c, cx_, ry, cw_, row_h2, fc, GREY)
            c.setFont("Helvetica-Bold" if ci == 0 else "Helvetica", 7)
            c.setFillColor(NAVY if ci == 0 else colors.black)
            c.drawCentredString(cx_ + cw_/2, ry + 2.5*mm, cell)

    y -= (len(rows2) + 2) * row_h2 + 5*mm

    # ── 3-column treatment boxes ───────────────────────────────────────────────
    section_title(c, 12*mm, y, "STEP 2 — IMMEDIATE TREATMENT")
    y -= 7*mm

    col3_w = (W - 26*mm) / 3
    col3_h = 52*mm
    col3_data = [
        (GREEN, "MILD\nExacerbation",
         [
          "1. ICS-formoterol 1-2 puffs PRN",
          "   OR salbutamol 4-10 puffs",
          "   via spacer q20min x3",
          "",
          "2. Shake MDI before each puff!",
          "   [GINA 2026 safety note]",
          "",
          "3. Monitor SpO2",
          "",
          "4. If no improvement in 1 hour",
          "   --> REFER to ED",
         ]),
        (AMBER, "MODERATE\nExacerbation",
         [
          "1. Salbutamol 4-10 puffs via spacer",
          "   OR nebuliser q20min x3",
          "",
          "2. Ipratropium 4-8 puffs q20min",
          "   (add-on bronchodilation)",
          "",
          "3. O2 ONLY if SpO2 <92%",
          "   Target: 92-95% (NOT >95%)",
          "",
          "4. Prednisolone 40-50mg PO",
          "",
          "5. Reassess every 20 min",
          "   Transfer if no improvement",
         ]),
        (RED, "SEVERE / LIFE-THREATENING",
         [
          "1. CALL FOR HELP / transfer NOW",
          "",
          "2. ANAPHYLAXIS present?",
          "   --> Epinephrine 0.5mg IM FIRST",
          "   THEN bronchodilator [GINA 2026]",
          "",
          "3. Continuous nebulised salbutamol",
          "   + ipratropium",
          "",
          "4. IV methylprednisolone 1mg/kg",
          "",
          "5. O2 to keep SpO2 92-95%",
          "",
          "6. IV magnesium sulphate 2g over",
          "   20 min (if no response)",
          "",
          "7. Prepare for ICU",
         ]),
    ]
    for i, (col, title, items_) in enumerate(col3_data):
        cx_ = 12*mm + i * (col3_w + 1*mm)
        box(c, cx_, y - col3_h, col3_w, col3_h, LTRED if col == RED else (LTAMB if col == AMBER else LTGREEN), col, radius=5)
        c.setFont("Helvetica-Bold", 9)
        c.setFillColor(col)
        for ti, tl in enumerate(title.split("\n")):
            c.drawCentredString(cx_ + col3_w/2, y - 7*mm - ti*5*mm, tl)
        c.setFont("Helvetica", 7)
        c.setFillColor(colors.black)
        item_y = y - 17*mm
        for item in items_:
            c.drawString(cx_ + 3*mm, item_y, item)
            item_y -= 3.5*mm

    y -= col3_h + 5*mm

    # ── Discharge / follow-up ──────────────────────────────────────────────────
    section_title(c, 12*mm, y, "STEP 3 — DISCHARGE & FOLLOW-UP  (GINA 2026)")
    y -= 7*mm

    box(c, 12*mm, y - 24*mm, W - 24*mm, 24*mm, LTBLUE, BLUE)
    items_d = [
        "Before discharge: review and correct inhaler technique  |  Provide written Asthma Action Plan",
        "Prescribe: 5-7 days prednisolone 40-50mg/day (complete course)  |  Step up controller therapy",
        "Arrange OPD follow-up within 2-7 days (high risk) or 1-3 months (stable)",
        "Red flag education: SpO2 <92%, can't speak full sentences, silent chest = call emergency immediately",
    ]
    for i, item in enumerate(items_d):
        c.setFont("Helvetica", 7.5)
        c.setFillColor(NAVY)
        c.drawString(15*mm, y - 7*mm - i*4.5*mm, f"\u2022 {item}")

    c.showPage()


# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 4 – SPECIAL SITUATIONS + BIOLOGICS + OPD CHECKLIST
# ═══════════════════════════════════════════════════════════════════════════════

def page4_special(c):
    c.setPageSize(A4)
    page_header(c, "PAGE 4 — BIOLOGICS, SPECIAL SITUATIONS & OPD CHECKLIST",
                "GINA 2026 Severe Asthma Guide + Pregnancy + Referral Criteria", 4, 4)
    page_footer(c)

    y = H - 48*mm

    # ── A: Biologics ───────────────────────────────────────────────────────────
    section_title(c, 12*mm, y, "A. BIOLOGIC THERAPY  (Step 5 — Severe Asthma)")
    y -= 7*mm

    bios = [
        (BLUE,   "Omalizumab",       "Anti-IgE",       "Allergic asthma, high serum IgE, sensitized allergens. IgE 30-1500 IU/mL."),
        (GREEN,  "Mepolizumab",      "Anti-IL-5",       "Eosinophilic asthma. Blood eos >=150 cells/uL (>=300 for step-up)."),
        (AMBER,  "Benralizumab",     "Anti-IL-5Ra",     "Eosinophilic asthma. Blood eos >=300 cells/uL. Dosing q8wk after loading."),
        (PURPLE, "Dupilumab",        "Anti-IL-4Ra",     "Type 2 asthma + comorbid CRS/nasal polyps/atopic dermatitis."),
        (ORANGE, "Tezepelumab",      "Anti-TSLP",       "Broadest biologic - works in type 2 AND non-type 2. Eos >=300 for best response."),
        (RED,    "Depemokimab",      "Anti-IL-5 (LA)",  "NEW GINA 2026. Ultra-long acting anti-IL-5. Dosing every 6 MONTHS."),
    ]
    bh = 9*mm
    bw = W - 24*mm
    for i, (col, name, mech, desc) in enumerate(bios):
        by = y - i * (bh + 1*mm)
        box(c, 12*mm, by - bh, bw, bh, LTGREY, col, radius=4)
        box(c, 12*mm, by - bh, 32*mm, bh, col, col, radius=4)
        c.setFont("Helvetica-Bold", 8)
        c.setFillColor(WHITE)
        c.drawString(14*mm, by - bh/2 - 1.5*mm, name)
        c.setFont("Helvetica-Bold", 7.5)
        c.setFillColor(col)
        c.drawString(46*mm, by - bh/2 - 1.5*mm, mech)
        c.setFont("Helvetica", 7.5)
        c.setFillColor(colors.black)
        c.drawString(78*mm, by - bh/2 - 1.5*mm, desc)

    y -= len(bios) * (bh + 1*mm) + 6*mm

    # ── B: Special Situations ─────────────────────────────────────────────────
    half_w = (W - 26*mm) / 2
    section_title(c, 12*mm, y, "B. SPECIAL SITUATIONS")
    y -= 7*mm

    # Pregnancy box
    box(c, 12*mm, y - 36*mm, half_w, 36*mm, LTPUR, PURPLE)
    c.setFont("Helvetica-Bold", 9)
    c.setFillColor(PURPLE)
    c.drawString(14*mm, y - 5*mm, "ASTHMA IN PREGNANCY")
    c.setFont("Helvetica", 7.5)
    c.setFillColor(colors.black)
    preg = [
        "Affects 4-8% of pregnancies",
        "Poorly controlled asthma risks:",
        "  preeclampsia, preterm birth,",
        "  low birth weight, IUGR, perinatal death",
        "ICS: SAFE - budesonide preferred",
        "SABA: safe; LABA: use with ICS only",
        "OCS: benefit outweighs risk when needed",
        "Monitor: serial spirometry, home PEF",
        "KEY: risks of poor control >> drug risks",
    ]
    for i, p in enumerate(preg):
        c.drawString(14*mm, y - 11*mm - i*3.2*mm, p)

    # Occupational box
    box(c, 12*mm + half_w + 2*mm, y - 36*mm, half_w, 36*mm, LTAMB, AMBER)
    c.setFont("Helvetica-Bold", 9)
    c.setFillColor(AMBER)
    c.drawString(14*mm + half_w + 2*mm, y - 5*mm, "OCCUPATIONAL ASTHMA")
    c.setFont("Helvetica", 7.5)
    c.setFillColor(colors.black)
    occ = [
        "Suspect if: adult onset, symptoms",
        "improve on weekends/holidays,",
        "specific occupational exposure",
        "(baker, painter, nurse, farmer)",
        "",
        "Workup: serial PEF at work vs rest",
        "Methacholine challenge",
        "",
        "Treatment:",
        "REMOVE FROM EXPOSURE (1st step!)",
        "ATS: reassess >=2 years post-removal",
    ]
    for i, o in enumerate(occ):
        c.drawString(14*mm + half_w + 4*mm, y - 11*mm - i*3.2*mm, o)

    y -= 36*mm + 5*mm

    # ── C: OPD Checklist ──────────────────────────────────────────────────────
    section_title(c, 12*mm, y, "C. OPD VISIT CHECKLIST  (Every Asthma Appointment)")
    y -= 7*mm

    chk_w = (W - 26*mm) / 2
    chk_h = 44*mm

    box(c, 12*mm, y - chk_h, chk_w, chk_h, LTBLUE, BLUE)
    c.setFont("Helvetica-Bold", 8.5)
    c.setFillColor(NAVY)
    c.drawString(14*mm, y - 5*mm, "FIRST VISIT (New Patient)")
    c.setFont("Helvetica", 7.5)
    c.setFillColor(colors.black)
    first = [
        "[ ] Symptom history (all 4 features)",
        "[ ] Trigger history (allergens, exercise, ASA)",
        "[ ] Atopic & family history",
        "[ ] Prior hospitalizations / ICU admissions",
        "[ ] Current medications (beta-blockers?)",
        "[ ] Spirometry + bronchodilator test",
        "[ ] Chest X-ray",
        "[ ] CBC, IgE, FeNO",
        "[ ] Start GINA step treatment",
        "[ ] Teach inhaler technique (DEMONSTRATE!)",
        "[ ] Provide written Asthma Action Plan",
    ]
    for i, f in enumerate(first):
        c.drawString(14*mm, y - 11*mm - i*3.1*mm, f)

    box(c, 12*mm + chk_w + 2*mm, y - chk_h, chk_w, chk_h, LTGREEN, GREEN)
    c.setFont("Helvetica-Bold", 8.5)
    c.setFillColor(GREEN)
    c.drawString(14*mm + chk_w + 2*mm, y - 5*mm, "FOLLOW-UP VISIT")
    c.setFont("Helvetica", 7.5)
    c.setFillColor(colors.black)
    fu = [
        "[ ] Reliever use this week? (>2x = uncontrolled)",
        "[ ] Night waking?",
        "[ ] Activity limitation?",
        "[ ] Any exacerbations / ED visits / OCS?",
        "[ ] Missed doses?",
        "[ ] WATCH INHALER TECHNIQUE",
        "[ ] Check SpO2",
        "[ ] Assess control (GINA table)",
        "[ ] Step up or down?",
        "[ ] Screen comorbidities (rhinitis, GERD, OSA)",
        "[ ] Referral if step 3-4 uncontrolled",
    ]
    for i, f in enumerate(fu):
        c.drawString(14*mm + chk_w + 4*mm, y - 11*mm - i*3.1*mm, f)

    y -= chk_h + 5*mm

    # ── D: Referral criteria ──────────────────────────────────────────────────
    box(c, 12*mm, y - 16*mm, W - 24*mm, 16*mm, LTRED, RED)
    c.setFont("Helvetica-Bold", 9)
    c.setFillColor(RED)
    c.drawString(14*mm, y - 5.5*mm, "REFER TO PULMONOLOGIST / SPECIALIST:")
    c.setFont("Helvetica", 7.5)
    c.setFillColor(colors.black)
    refs = ("Diagnosis uncertain  |  Poor control despite Step 3-4  |  Suspected severe/difficult asthma  |  "
            "Biologics candidate  |  Occupational asthma  |  >=2 severe exacerbations/year  |  "
            "Prior near-fatal attack (ICU/intubation)")
    c.drawString(14*mm, y - 11*mm, refs)

    c.showPage()


# ── MAIN ──────────────────────────────────────────────────────────────────────

OUTPUT = "/home/daytona/workspace/asthma-flowchart/OPD_Asthma_Flowchart_GINA2026.pdf"

c = canvas.Canvas(OUTPUT, pagesize=A4)
c.setTitle("OPD Asthma Clinical Decision Flowchart - GINA 2026")
c.setAuthor("Clinical Decision Support - Murray & Nadel / GINA 2026")
c.setSubject("Asthma Diagnosis & Management")

page1_diagnosis(c)
page2_control_treatment(c)
page3_acute(c)
page4_special(c)

c.save()
print(f"PDF saved to: {OUTPUT}")
Running Command

cd /home/daytona/workspace/asthma-flowchart && python generate_flowchart.py 2>&1

Editing File

~/asthma-flowchart/generate_flowchart.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/asthma-flowchart/generate_flowchart.py'
Editing File

~/asthma-flowchart/generate_flowchart.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/asthma-flowchart/generate_flowchart.py'
Running Command

cd /home/daytona/workspace/asthma-flowchart && python generate_flowchart.py 2>&1

Running Command

ls -lh /home/daytona/workspace/asthma-flowchart/OPD_Asthma_Flowchart_GINA2026.pdf && python3 -c "from pypdf import PdfReader; r=PdfReader('/home/daytona/workspace/asthma-flowchart/OPD_Asthma_Flowchart_GINA2026.pdf'); print(f'Pages: {len(r.pages)}')"

Your PDF is ready - 4 pages, A4, colour-coded, print-ready:

OPD Asthma Flowchart GINA2026

PDF Document · PDF


Here's what's inside each page:
Page 1 - Diagnosis Algorithm
  • Step-by-step flowchart from symptom presentation to confirmed diagnosis
  • Two decision diamonds (variable symptoms? + spirometry results?)
  • Spirometry criteria box (FEV1/FVC, bronchodilator reversibility thresholds)
  • Additional workup panel (CBC, IgE, FeNO, peak flow diary)
  • Right sidebar listing red-flag differential diagnoses (COPD, VCD, heart failure, PE, bronchiectasis)
Page 2 - Control Assessment & Treatment Steps
  • GINA control table (well controlled / partly controlled / uncontrolled) with colour coding
  • All 5 GINA 2026 treatment steps with step badges, severity labels, and full drug details
  • ICS-SABA AIR at Step 1 highlighted as new GINA 2026 addition
  • Step-up / step-down guidance boxes at the bottom
Page 3 - Acute Exacerbation Management
  • Severity table: mild / moderate / severe / life-threatening (speech, SpO2, RR, PEF, wheeze, HR)
  • Three treatment columns (mild, moderate, severe) with drug doses and actions
  • GINA 2026 updates highlighted: shake MDI before use, O2 only if SpO2 <92%, epinephrine first in anaphylaxis
  • Discharge & follow-up checklist
Page 4 - Biologics, Special Situations & OPD Checklist
  • All 6 biologics table (omalizumab through depemokimab) with mechanism and patient selection criteria
  • Asthma in pregnancy box (drug safety, monitoring, key risks)
  • Occupational asthma box
  • First visit and follow-up visit checklists side by side
  • Referral criteria banner at the bottom

Can you explain classsification and phenotypes of asthma and meaning of mild intermittent persistent intermittent partially controlled

Finding Sources
Searching the Web

GINA 2026 asthma classification severity intermittent persistent mild moderate severe phenotypes

Finding Sources
Finding Sources
Finding Sources
Reading Web Page

https://ginasthma.org/wp-content/uploads/2026/05/GINA-2026-S…

Reading File
I have everything I need. Let me now deliver a clear, complete answer.

Asthma Classification, Severity, and Phenotypes - Fully Explained


THE BIG PICTURE FIRST: Two Different Systems, One Disease

There are two parallel classification systems in use. This is the main source of confusion. Understanding which system you are using clears everything up.
SystemUsed ByClassifies Based OnTerms Used
NAEPP/EPR-3 (USA, older)NHLBI, most textbooksSymptoms BEFORE treatmentIntermittent, Mild Persistent, Moderate Persistent, Severe Persistent
GINA (global, modern)GINA 2026, most current guidelinesControl WHILE on treatmentWell controlled, Partly controlled, Uncontrolled + Severity by step
GINA 2026 says: The old intermittent/persistent classification was based on an arbitrary, untested assumption that patients with symptoms ≤2 days/week would not benefit from ICS. This is now known to be wrong - even "intermittent" asthma patients can have severe or fatal exacerbations. GINA now strongly prefers the control-based framework.
Both systems are still taught and used clinically, so you need to understand both.

PART 1: THE NAEPP SEVERITY CLASSIFICATION (Traditional System)

How to Use It:

  • Applied to patients before starting treatment, or when treatment has just been initiated
  • Based on the most severe feature - if a patient has one moderate feature, they are classified as moderate, even if everything else is mild
  • 4 categories: Intermittent + 3 types of Persistent

🟢 STAGE 1: MILD INTERMITTENT

Think of it as: "Comes and goes, rarely bothers me"
ParameterCriteria
Daytime symptoms≤2 days per week
Night waking≤2 nights per month
SABA use for symptoms≤2 days per week
Activity limitationNone
FEV1 / PEF≥80% predicted
PEF variability<20%
Simple memory: "2-2-2 rule" - symptoms ≤2 days/week, night symptoms ≤2/month, SABA ≤2/week
Clinical meaning: The patient has asthma but is largely fine. Symptoms are infrequent, lung function is normal between episodes.
Old treatment (NAEPP): SABA only as needed (PRN) GINA 2026 says: Even these patients should receive ICS-containing therapy because they can still have fatal exacerbations. No more SABA-alone at any stage.

🟡 STAGE 2: MILD PERSISTENT

Think of it as: "More than twice a week, but not every day"
ParameterCriteria
Daytime symptoms>2 days/week but NOT daily
Night waking3-4 nights/month
SABA use>2 days/week but not daily
Activity limitationMinor
FEV1 / PEF≥80% predicted
PEF variability20-30%
Simple memory: Crosses the "2 days" threshold but hasn't reached "daily"
Clinical meaning: The patient needs daily controller medication. ICS should be started. Lung function is still normal or near-normal.
Key point: This is the stage where clinicians most often under-treat - they see someone with symptoms 3x/week and assume SABA is enough. It is not.

🟠 STAGE 3: MODERATE PERSISTENT

Think of it as: "Daily symptoms, affecting daily life"
ParameterCriteria
Daytime symptomsDaily
Night waking>1 night/week but not nightly
SABA useDaily
Activity limitationSome limitation
FEV1 / PEF60-79% predicted
PEF variability>30%
Clinical meaning: Airways are significantly inflamed. Lung function is measurably reduced. This patient needs medium-dose ICS + LABA, likely.

🔴 STAGE 4: SEVERE PERSISTENT

Think of it as: "Symptoms throughout the day, every night"
ParameterCriteria
Daytime symptomsContinuous / throughout day
Night wakingFrequently (nightly)
SABA useSeveral times daily
Activity limitationExtremely limited
FEV1 / PEF<60% predicted
PEF variability>30%
Clinical meaning: Severely impaired airway function. Requires high-dose ICS+LABA; may need add-on therapy, OCS, or biologics.

PART 2: THE GINA CONTROL-BASED SYSTEM (Modern, Preferred)

GINA moved away from "severity before treatment" because by the time a patient comes to you, they're already on some treatment. Classifying their pre-treatment state is often guesswork.
GINA asks: "How controlled is this patient RIGHT NOW, on their current treatment?"

🟢 Well Controlled (All 4 criteria met)

FeatureCriterion
Daytime symptoms≤2 days/week
Night wakingNone
Reliever use≤2 days/week
Activity limitationNone
Patient is doing well. Consider stepping down treatment after 3 months of stability.

🟡 Partly Controlled (1-2 features present)

Patient has some features but not fully out of control. Step up treatment.

🔴 Uncontrolled (3-4 features present)

Patient has significant symptom burden. Step up immediately. Check inhaler technique and adherence first before escalating.

GINA Severity (assessed retrospectively, by treatment step needed):

SeverityWhat it means
MildWell controlled on GINA Step 1-2
ModerateWell controlled on GINA Step 3
SevereRequires Step 4-5 to stay controlled, OR uncontrolled despite Step 4-5

PART 3: ASTHMA PHENOTYPES (The Modern View)

"Asthma is a heterogeneous disease, with various underlying disease processes. Recognizable clusters of demographic, clinical and/or pathophysiological characteristics are often called asthma phenotypes."
  • GINA 2026
A phenotype is "what it looks like on the outside" - clinical and demographic patterns. An endotype is "what's driving it on the inside" - the actual biological mechanism.

Clinical Phenotypes:


1. Allergic Asthma (Most Common)

  • Who: Usually starts in childhood; family/personal history of eczema, hay fever, allergic rhinitis
  • Triggers: Dust mites, pollen, pets, cockroach, mold
  • Lab clue: Elevated IgE, positive skin prick test, blood eosinophilia
  • Endotype: Type 2 inflammation (IgE-mediated, Th2, IL-4/IL-5/IL-13)
  • Treatment response: Excellent with ICS; biologics: omalizumab (anti-IgE)
  • GINA note: Most easily recognized phenotype

2. Non-Allergic Asthma

  • Who: Often adult-onset, no atopic history, no elevated IgE
  • Triggers: Infections, irritants, exercise, cold air, stress
  • Lab clue: No eosinophilia; IgE normal; negative skin tests
  • Endotype: Neutrophilic or paucigranulocytic (Type 2-low)
  • Treatment: ICS still helps but less dramatically; biologics are less effective (tezepelumab works best here)

3. Late-Onset Asthma (Adult-Onset)

  • Who: Women >40 years old, often non-atopic
  • Character: Often more severe, less responsive to corticosteroids
  • Association: Obesity, hormonal changes, GERD
  • Clinical pearl: These patients are often misdiagnosed or under-treated for years

4. Asthma with Persistent Airflow Limitation (Overlap / ACO)

  • Who: Long-standing asthma with chronic airway remodeling; may also have smoking history
  • Character: Fixed or partially-reversible airflow obstruction (FEV1 does not fully normalize)
  • Confusion: Can look like COPD; look for history of childhood asthma, atopy, eosinophilia
  • Term: Asthma-COPD Overlap (ACO) - not a single disease but a description

5. Asthma with Obesity

  • Who: BMI >30; more common in women
  • Character: Symptoms often non-eosinophilic, frequent, hard to control; dyspnoea partly mechanical
  • Treatment: Weight loss is a legitimate therapeutic intervention; often needs higher step treatment
  • Caution: Not always classic Type 2 inflammation - may not respond to standard ICS as well

6. Exercise-Induced Bronchoconstriction (EIB)

  • Who: Athletes; may be the sole manifestation of asthma in some patients
  • Character: Cough, wheeze, breathlessness 5-15 minutes after (not during) exercise; resolves spontaneously in 30-60 min
  • Diagnosis: Exercise challenge test - FEV1 fall ≥10% after exercise
  • Treatment: Pre-exercise ICS-formoterol or SABA; regular ICS reduces EIB significantly

7. Aspirin/NSAID-Exacerbated Respiratory Disease (AERD)

  • Who: Classic triad: asthma + chronic rhinosinusitis + nasal polyps
  • Trigger: Aspirin, NSAIDs (ibuprofen, diclofenac, naproxen) - within 30-180 min of ingestion
  • Mechanism: COX-1 inhibition diverts arachidonic acid to leukotriene pathway → massive bronchoconstriction
  • Lab clue: Urinary LTE4 elevated at baseline
  • Treatment: ICS + leukotriene receptor antagonists (montelukast); aspirin desensitization in specialist centres
  • Clinical warning: Always ask about NSAID use in every asthma patient

8. Eosinophilic Asthma (Severe Phenotype)

  • Who: Often adult-onset; may or may not be allergic; peripheral eosinophilia ≥150-300 cells/µL
  • Character: Severe, frequent exacerbations; oral-corticosteroid dependent in some
  • FeNO: Usually >25 ppb (type 2 airway inflammation marker)
  • Treatment: Excellent response to anti-IL-5 biologics (mepolizumab, benralizumab, reslizumab)

9. Occupational Asthma

  • Who: Baker, painter, spray painter, healthcare worker, farmer, hairdresser
  • Character: Symptoms improve on days away from work (weekends, holidays) - this is the diagnostic clue
  • Diagnosis: Serial PEF at work vs rest; methacholine challenge
  • Treatment: Remove from exposure (most important); ICS for ongoing inflammation

PART 4: HOW THE TWO SYSTEMS MAP TOGETHER (The Confusion Resolved)

OLD NAEPP (before treatment)        GINA (on treatment)
─────────────────────────────────   ──────────────────────────────────
Mild Intermittent    ──────────────> Controlled on Step 1 = Mild asthma

Mild Persistent      ──────────────> Controlled on Step 2 = Mild asthma

Moderate Persistent  ──────────────> Controlled on Step 3 = Moderate asthma

Severe Persistent    ──────────────> Needs Step 4-5 to control = Severe asthma
                                     Uncontrolled on Step 4-5 = Severe refractory

PART 5: CLINICIAN PEARL - The Terminology Trap

One of the commonest errors in OPD:
A patient comes in and says "my doctor told me I have mild asthma." You see them on salbutamol only. You think: mild = fine = no ICS needed.
This is wrong. Here is why:
  1. "Mild asthma" in NAEPP terms means before treatment classification. On GINA, mild means controlled on low-step treatment.
  2. GINA 2026 explicitly states: the old intermittent/persistent distinction was arbitrary and not evidence-based. Patients labelled "intermittent" can die from their asthma.
  3. Every asthma patient - regardless of how "mild" their symptoms appear - should be on ICS-containing therapy.
  4. The correct question to ask is not "how severe is this asthma?" but rather "is this asthma controlled on current treatment?"

QUICK REFERENCE SUMMARY TABLE

TermSystemSimple MeaningKey Numbers
Mild IntermittentNAEPPOccasional, rare symptomsDaytime ≤2/wk, Night ≤2/month, FEV1 ≥80%
Mild PersistentNAEPPMore than twice a week, not dailyDaytime >2/wk, Night 3-4/month, FEV1 ≥80%
Moderate PersistentNAEPPDaily symptoms, some limitationDaily symptoms, Night >1/wk, FEV1 60-79%
Severe PersistentNAEPPConstant symptoms, severe limitationContinuous, Nightly, FEV1 <60%
Well ControlledGINACurrent treatment is working0 of 4 features
Partly ControlledGINATreatment partially working1-2 of 4 features
UncontrolledGINATreatment not working3-4 of 4 features
Mild asthma (GINA)GINA severityControlled on Steps 1-2Needs low-dose ICS only
Severe asthma (GINA)GINA severityNeeds Step 4-5 to controlHigh-dose ICS+LABA ± add-ons

Sources:
  • GINA 2026 Strategy Report - Official full report, May 2026
  • Textbook of Family Medicine 9e (Rakel) - NAEPP/EPR-3 classification tables
  • Murray & Nadel's Textbook of Respiratory Medicine - phenotype descriptions

Dose of ics formetrol

Finding Sources
Searching the Web

GINA 2026 ICS formoterol dose budesonide formoterol MART AIR low medium high dose table mcg

Your credits are exhausted. You can purchase a top-up or subscribe to a plan to continue using Orris. If you're already subscribed, your daily credits will reset tomorrow.

Create a detailed ICS-formoterol dosing reference table in PDF

Your credits are exhausted. You can purchase a top-up or subscribe to a plan to continue using Orris. If you're already subscribed, your daily credits will reset tomorrow.
This is a shared conversation. Sign in to Orris to start your own chat.