// ============================================================ // BEDSIDE PANELS (second batch) — neonatal, respiratory, // ventilation, sepsis, burns. Completes parity with the 15 // vanilla Bedside sub-modules. Drug per-kg + max values ported // byte-for-byte from public/js/bedside/.js. // ============================================================ import { useState } from 'react'; import { formatDose } from '@shared/clinical/calculators'; import { neonatalAssess, type Sex } from '@shared/clinical/fenton'; const card = 'rounded-lg border border-border bg-card p-5 space-y-3'; const input = 'w-full rounded-md border border-input bg-background px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-ring'; const label = 'block text-xs font-medium text-muted-foreground'; const th = 'text-left px-2 py-1.5 border-b border-border font-semibold uppercase tracking-wide text-[10px] text-muted-foreground'; const td = 'px-2 py-1.5 border-b border-border align-top text-sm'; function Dose({ label: l }: { label: string }) { const i = l.indexOf('('); if (i < 0) return {l}; return {l.slice(0, i).trim()}{' '}{l.slice(i)}; } function DrugTable({ children, notes = true }: { children: React.ReactNode; notes?: boolean }) { return (
{notes && }{children}
DrugDoseRouteNotes
); } function Row({ name, dose, route, notes }: { name: string; dose: React.ReactNode; route: string; notes?: string }) { return ( {dose} {route} {notes !== undefined && } ); } // ── Neonatal ──────────────────────────────────────────────── export function NeonatalPanel() { const [weeks, setWeeks] = useState(''); const [days, setDays] = useState('0'); const [wtG, setWtG] = useState(''); const [sex, setSex] = useState('male'); const [kgForNrp, setKgForNrp] = useState(''); const [apgarScores, setApgarScores] = useState>({ appearance: 2, pulse: 2, grimace: 2, activity: 2, respiration: 2 }); const weeksNum = Number.parseInt(weeks, 10); const daysNum = Number.parseInt(days, 10) || 0; const wtNum = Number.parseFloat(wtG); const validAssess = Number.isFinite(weeksNum) && weeksNum >= 22 && weeksNum <= 44 && Number.isFinite(wtNum) && wtNum > 0; const assess = validAssess ? neonatalAssess(weeksNum, daysNum, wtNum, sex) : null; const kg = Number.parseFloat(kgForNrp); const validKg = Number.isFinite(kg) && kg > 0; const epiIvLow = validKg ? Math.round(kg * 0.01 * 100) / 100 : 0; const epiIvHigh = validKg ? Math.round(kg * 0.03 * 100) / 100 : 0; const epiEtLow = validKg ? Math.round(kg * 0.05 * 100) / 100 : 0; const epiEtHigh = validKg ? Math.round(kg * 0.1 * 100) / 100 : 0; const ns = validKg ? Math.round(kg * 10) : 0; const d10 = validKg ? Math.round(kg * 2 * 10) / 10 : 0; const apgarTotal = Object.values(apgarScores).reduce((s, v) => s + v, 0); const apgarSeverity = apgarTotal >= 7 ? 'Reassuring' : apgarTotal >= 4 ? 'Moderately depressed' : 'Severely depressed'; const apgarColor = apgarTotal >= 7 ? 'text-green-600 bg-green-50' : apgarTotal >= 4 ? 'text-amber-600 bg-amber-50' : 'text-destructive bg-red-50'; const apgarGuidance = apgarTotal >= 7 ? 'Routine newborn care. Continue reassessment. Repeat at 5 min.' : apgarTotal >= 4 ? 'Stimulate, clear airway, warm. Give O₂ if cyanotic. Ventilate with PPV if HR <100 or apneic/gasping. Reassess q30 sec.' : 'Full NRP pathway — PPV immediately. Intubate if PPV ineffective. Chest compressions if HR <60. Epinephrine and volume per NRP.'; return (

Neonatal Assessment + NRP + Apgar

{/* Assessment */}

Gestational age + size assessment (Fenton 2013)

setWeeks(e.target.value)} data-testid="neo-weeks" />
setDays(e.target.value)} data-testid="neo-days" />
setWtG(e.target.value)} data-testid="neo-weight" />
{assess && (
Gestational Age
{assess.gaClass.label}
{weeksNum} wk {daysNum} d ({assess.gaDecimal.toFixed(1)} wk)
Weight for Gestational Age
{assess.weightClass.label}
{assess.percentile.toFixed(1)}th percentile · {assess.weightClass.detail}
Birth Weight Category
{assess.bwClass.label}
{wtNum} g ({(wtNum / 1000).toFixed(2)} kg)
Fenton ({sex})
Expected weight (M): {assess.expectedWeight} g
Z-score: {assess.z.toFixed(2)}
Percentile: {assess.percentile.toFixed(1)}%
)} {/* NRP pathway */}

NRP pathway (AHA/AAP 8th ed 2020)

BIRTH — ASSESS (first 30 sec)
Term? Tone? Breathing/crying? All yes → routine care. Any no → warm, dry, stimulate, clear airway PRN, evaluate HR + resp.
HR <100 OR apneic/gasping (60 s)
Start PPV 40-60 breaths/min, room air for term / 21-30% for preterm. Attach SpO₂ (right hand) ± ECG. MR SOPA if ineffective.
HR <100 after 30 s effective PPV
Reassess ventilation — ensure chest rise. Consider increasing FiO₂, intubation, or LMA. Continue PPV.
HR <60 after 30 s effective PPV
Intubate + chest compressions — 3:1 ratio (90 compressions + 30 breaths/min), FiO₂ 100%, lower 1/3 sternum, depth 1/3 AP chest.
HR <60 despite compressions + PPV × 60 s
Epinephrine 1:10,000 (0.1 mg/mL): IV/IO 0.01-0.03 mg/kg (0.1-0.3 mL/kg) — preferred. ETT 0.05-0.1 mg/kg. Repeat q3-5 min. Hypovolemia: NS 10 mL/kg IV/IO over 5-10 min.
Target SpO₂ (preductal):
1 min 60-65% · 2 min 65-70% · 3 min 70-75% · 4 min 75-80% · 5 min 80-85% · 10 min 85-95%
Initial ETT size:
<1 kg / <28 wk: 2.5 · 1-2 kg / 28-34 wk: 3.0 · 2-3 kg / 34-38 wk: 3.5 · >3 kg / >38 wk: 3.5-4.0
ETT depth (lip): ~6 + weight(kg) cm

NRP drug doses

setKgForNrp(e.target.value)} data-testid="nrp-weight" />
{validKg ? ( } route="IV / IO" notes="Preferred route. Repeat q3-5 min." /> } route="ETT" notes="While IV being placed." /> } route="IV / IO" notes="Over 5-10 min for volume. Repeat PRN." /> } route="IV slow push" notes="For documented hypoglycemia. Then D10 infusion 4-6 mg/kg/min." /> ) :

Enter weight (kg) to see NRP doses.

}
Concentration note: NRP uses epinephrine 1:10,000 (0.1 mg/mL). NOT 1:1000 (1 mg/mL) — that is IM for anaphylaxis / older patients.
{/* Apgar */}

Apgar score

{[ ['appearance', 'Appearance', ['Blue/pale', 'Body pink, extremities blue', 'All pink']], ['pulse', 'Pulse', ['Absent', '<100 bpm', '≥100 bpm']], ['grimace', 'Grimace', ['No response', 'Grimace', 'Cough/sneeze']], ['activity', 'Activity', ['Limp', 'Some flexion', 'Active motion']], ['respiration', 'Respiration', ['Absent', 'Slow/irregular', 'Good/crying']], ].map(([key, lab, options]) => (
))}
Apgar: {apgarTotal}/10 — {apgarSeverity}
{apgarGuidance}
Fenton TR, Kim JH. BMC Pediatr 2013;13:59 · NRP 8th ed (AHA/AAP 2020) · Apgar is a description of status — never delay resuscitation while scoring.
); } // ── Respiratory ───────────────────────────────────────────── export function RespiratoryPanel() { const [mode, setMode] = useState<'asthma' | 'pram' | 'croup' | 'bronch'>('asthma'); const [weight, setWeight] = useState(''); const wt = Number.parseFloat(weight); const valid = Number.isFinite(wt) && wt > 0; const f = (perKg: number, max: number | null, unit = 'mg') => (valid ? formatDose(wt, perKg, max, unit) : null); const [asthmaSev, setAsthmaSev] = useState<'mild' | 'moderate' | 'severe' | null>(null); // PRAM inputs (0-12 total) const [pram, setPram] = useState({ spo2: 0, retractions: 0, scalene: 0, air: 0, wheeze: 0 }); const pramTotal = Object.values(pram).reduce((s, v) => s + v, 0); const pramSev = pramTotal <= 3 ? 'Mild' : pramTotal <= 7 ? 'Moderate' : 'Severe'; const pramColor = pramTotal <= 3 ? 'text-green-600 bg-green-50' : pramTotal <= 7 ? 'text-amber-600 bg-amber-50' : 'text-destructive bg-red-50'; // Croup / Westley (0-17) const [croup, setCroup] = useState({ conscious: 0, cyanosis: 0, stridor: 0, air: 0, retractions: 0 }); const croupTotal = Object.values(croup).reduce((s, v) => s + v, 0); const croupSev = croupTotal <= 2 ? 'Mild' : croupTotal <= 5 ? 'Moderate' : croupTotal <= 11 ? 'Severe' : 'Impending Respiratory Failure'; const croupColor = croupTotal <= 2 ? 'text-green-600 bg-green-50' : croupTotal <= 5 ? 'text-amber-600 bg-amber-50' : croupTotal <= 11 ? 'text-destructive bg-red-50' : 'text-red-900 bg-red-100'; // Bronchiolitis inputs const [bronch, setBronch] = useState({ age: 'gte12w', spo2: 'ok', hydration: 'ok', distress: 'mild' }); const bronchAdmit = bronch.distress === 'severe' || bronch.spo2 === 'low' || bronch.hydration === 'poor' || bronch.age === 'lt12w'; return (

Respiratory

{(['asthma', 'pram', 'croup', 'bronch'] as const).map((m) => ( ))}
{mode !== 'pram' && mode !== 'bronch' && (
setWeight(e.target.value)} data-testid="resp-weight" />
)} {/* ASTHMA */} {mode === 'asthma' && ( <>
{(['mild', 'moderate', 'severe'] as const).map((s) => ( ))}
{asthmaSev && !valid &&

Enter weight (kg) to see doses.

} {asthmaSev === 'mild' && valid && ( <>

Speaks in sentences, no accessory muscle use, SpO₂ ≥94%

} route="Nebulized" notes="q20min × 3 doses" /> } route="PO/IV" notes="Single dose, or 2 days" /> } route="PO" notes="Alternative: 3-5 day course" /> )} {asthmaSev === 'moderate' && valid && ( <>

Speaks in phrases, some accessory muscle use, SpO₂ 90-93%

} route="Nebulized" notes="q20min × 3 doses, then continuous if needed" /> } route="PO/IV/IM" notes="Single dose" /> )} {asthmaSev === 'severe' && valid && ( <>

Speaks in words only, significant accessory muscle use, SpO₂ <90%. Consider ICU.

} route="Continuous neb" notes="Or 0.15-0.3 mg/kg q20min" /> } route="IV" notes="Or methylprednisolone 2 mg/kg IV (max 60 mg)" /> } route="IV" notes="Single dose, monitor BP" /> } route="IM" notes="If impending arrest / no IV access" /> } route="SC/IV" notes="Then 0.1-10 mcg/kg/min infusion" />
Continuous monitoring. Consider ICU admission. If no response to magnesium → terbutaline infusion. If impending respiratory failure → intubation (ketamine preferred induction agent).
)}
NAEPP/GINA guidelines. Always use clinical judgment.
)} {/* PRAM */} {mode === 'pram' && ( <>

Pediatric Respiratory Assessment Measure (PRAM) — for asthma exacerbation severity (0-12).

{[ ['spo2', 'SpO₂', ['≥95% (0)', '92-94% (1)', '<92% (2)']], ['retractions', 'Suprasternal retractions', ['Absent (0)', 'Present (2)']], ['scalene', 'Scalene muscle use', ['Absent (0)', 'Present (2)']], ['air', 'Air entry', ['Normal (0)', 'Mild ↓ at bases (1)', 'Widespread ↓ (2)', 'Absent/minimal (3)']], ['wheeze', 'Wheezing', ['Absent (0)', 'Expiratory only (1)', 'Ins+exp (2)', 'Audible without stethoscope/silent chest (3)']], ].map(([key, lab, options]) => (
))}
PRAM Score: {pramTotal}/12 — {pramSev}
Mild (0-3): outpatient management. Moderate (4-7): consider oral steroids + frequent bronchodilators. Severe (8-12): aggressive treatment, consider ICU.
)} {/* CROUP */} {mode === 'croup' && ( <>

Westley croup score (0-17).

{[ ['conscious', 'Level of consciousness', ['Normal (0)', 'Disoriented (5)']], ['cyanosis', 'Cyanosis', ['None (0)', 'With agitation (4)', 'At rest (5)']], ['stridor', 'Stridor', ['None (0)', 'With agitation (1)', 'At rest (2)']], ['air', 'Air entry', ['Normal (0)', 'Decreased (1)', 'Severely decreased (2)']], ['retractions', 'Retractions', ['None (0)', 'Mild (1)', 'Moderate (2)', 'Severe (3)']], ].map(([key, lab, options]) => (
))}
Westley: {croupTotal}/17 — {croupSev}
Mild ≤2 · Moderate 3-5 · Severe 6-11 · Impending failure ≥12.
{valid && ( } route={croupTotal <= 2 ? 'PO' : croupTotal <= 5 ? 'PO/IM' : 'IV/IM'} notes="Preferred corticosteroid; single dose" /> {croupTotal > 2 && } {croupTotal > 2 && } {croupTotal > 5 && } )} )} {/* BRONCHIOLITIS */} {mode === 'bronch' && ( <>
{bronchAdmit ? 'Admit / Observe' : 'Likely Safe for Discharge'}
{bronch.age === 'lt12w' &&
⚠ Age <12 weeks — high risk for apnea. Monitor closely.
}
NOT recommended (AAP 2014/2023): Albuterol/salbutamol (no benefit), epinephrine (no evidence), systemic corticosteroids (no benefit), antibiotics (unless bacterial co-infection), chest physiotherapy.
AAP Clinical Practice Guideline: Management of Bronchiolitis in Infants and Children (2014, reaffirmed 2023). RSV most common (50-80%).
)}
); } // ── Ventilation (O₂ escalation + vent settings reference) ─── export function VentilationPanel() { const [weight, setWeight] = useState(''); const [age, setAge] = useState(''); const wt = Number.parseFloat(weight); const ageY = Number.parseFloat(age); const validWt = Number.isFinite(wt) && wt > 0; const hfLow = validWt ? Math.round(wt * 1 * 10) / 10 : 0; const hfHigh = validWt ? Math.round(wt * 2 * 10) / 10 : 0; const tvLow = validWt ? Math.round(wt * 6 * 10) / 10 : 0; const tvHigh = validWt ? Math.round(wt * 8 * 10) / 10 : 0; const hasAge = Number.isFinite(ageY) && ageY >= 0; const rate = hasAge ? ageY < 0.1 ? '30-40' : ageY < 1 ? '25-35' : ageY < 5 ? '20-25' : ageY < 12 ? '16-20' : '12-16' : ''; return (

O₂ & Ventilation

setWeight(e.target.value)} data-testid="vent-weight" />
setAge(e.target.value)} data-testid="vent-age" />

Target SpO₂

Escalation ladder

1. Nasal cannula (low-flow)
0.5-6 L/min · FiO₂ ~24-40% · comfortable, no humidification. Good for mild hypoxia.
2. Simple face mask
6-10 L/min · FiO₂ 35-60%. Must keep flow >6 L/min to flush CO₂.
3. Non-rebreather mask
10-15 L/min · FiO₂ 60-90%. Reservoir bag must stay inflated.
4. High-flow nasal cannula (HFNC)
{validWt ? `1-2 L/kg/min = ${hfLow}-${hfHigh} L/min` : '1-2 L/kg/min'} · heated + humidified · FiO₂ 30-100% titratable · generates ~2-5 cmH₂O PEEP. Reassess at 1-2 h.
5. Non-invasive (CPAP / BiPAP)
CPAP 5-10 cmH₂O · BiPAP IPAP 10-14 / EPAP 5. Needs cooperative patient, intact airway reflexes, no copious secretions.
6. Intubate + mechanical ventilation
When NIV fails, airway compromised, apnea, or GCS ≤8. See Airway tab for RSI drugs.

Bag-Valve-Mask (BVM)

When: apnea, bradycardia (HR <60 neonate; inadequate breathing at any age), during resuscitation.
Rate: Newborn 40-60/min · Infant-child 20-30/min · Adolescent 10-12/min (1 breath q5-6 sec).
Tidal volume: 6-8 mL/kg — gentle chest rise only. Avoid over-ventilation.
Technique: head tilt / jaw thrust, E-C or 2-thumb mask seal, squeeze 1 sec, release fully.
Not ventilating? MR SOPA — Mask reseal, Reposition airway, Suction, Open mouth, Pressure ↑, Alternative airway.

Mechanical vent — starting settings

Mode: Volume-control OR Pressure-control. PRVC / SIMV-PS hybrids.
Tidal volume: {validWt ? `${tvLow}-${tvHigh} mL` : '6-8 mL/kg'} (6-8 mL/kg). Use 4-6 mL/kg for ARDS.
Rate: {rate ? `${rate}/min (age ${ageY} yr)` : 'Newborn 30-40 · Infant 25-35 · Child 16-20 · Adolescent 12-16'}.
PEEP: start 5 cmH₂O. Increase to 8-12+ for refractory hypoxia.
FiO₂: start 100%, wean rapidly to lowest that maintains target SpO₂.
I:E ratio: 1:2 normally; 1:3-4 for obstructive disease.
Plateau pressure: keep <30 cmH₂O (ideally <28).

Adjusting for gas exchange

Mental model: Oxygenation is mostly FiO₂ + PEEP. Ventilation (CO₂) is mostly rate + tidal volume. Obstructive (asthma, bronchiolitis) → long expiratory time, permissive hypercapnia. Restrictive (ARDS) → low TV, high PEEP, permissive hypercapnia + hypoxia.
AAP / PALS / AARC guidance.
); } // ── Sepsis ────────────────────────────────────────────────── export function SepsisPanel() { const [weight, setWeight] = useState(''); const [age, setAge] = useState<'neonate' | 'infant' | 'child'>('child'); const wt = Number.parseFloat(weight); const valid = Number.isFinite(wt) && wt > 0; const f = (perKg: number, max: number | null, unit = 'mg') => (valid ? formatDose(wt, perKg, max, unit) : null); const ageLbl = age === 'neonate' ? 'Neonate (0-28 d)' : age === 'infant' ? 'Young infant (29 d - 3 mo)' : 'Older child / adolescent'; const bolus = valid ? Math.round(wt * 20) : null; return (

Sepsis & Fever

setWeight(e.target.value)} data-testid="sepsis-weight" />
Sepsis approach — {ageLbl}{valid ? `, ${wt} kg` : ''}

Definition — Phoenix Sepsis Criteria (JAMA 2024)

Sepsis = suspected or confirmed infection + Phoenix Score ≥2 (organ dysfunction across respiratory, cardiovascular, coagulation, neurological).
Septic shock = sepsis + cardiovascular dysfunction (vasoactive support, or ↑lactate ≥5, or ↓MAP for age).
Previous SIRS-based criteria (Goldstein 2005) are now superseded.

Red flags

Abnormal behavior / mentation · Fever + ill-appearance · Tachycardia out of proportion to fever · Prolonged cap refill (>3 s) · Cold/mottled extremities · Weak pulses or wide pulse pressure ("warm shock") · Hypotension is a LATE sign · Any immune compromise / indwelling line.

Empirical therapy — {ageLbl}

{age === 'neonate' && <>Workup (full sepsis eval): CBC+diff, CRP, blood culture, UA+urine culture (cath), LP (CSF+HSV PCR), CXR if respiratory sx, procalcitonin. Early-onset (<72 h): GBS, E. coli, Listeria. Late-onset (>72 h): CoNS, S. aureus, gram-negs, Candida.} {age === 'infant' && <>Workup: Use validated rules — PECARN, Aronson, Rochester, Step-by-Step. CBC+ANC, procalcitonin/CRP, blood culture, UA+urine culture. Many warrant LP + admission + empiric abx. Coverage: GBS, E. coli, Listeria (up to ~6 wk), S. pneumo, N. meningitidis, H. flu, Salmonella.} {age === 'child' && <>Recognition: Phoenix score or clinical concern + suspected infection. Workup: CBC, CRP, procalcitonin, blood cx (+site-specific), lactate, blood gas, glucose, electrolytes, coags, LP if CNS concern. Source-directed imaging.}
{valid && ( {age === 'neonate' && <> } route="IV" notes="q8-12h. Covers GBS, Listeria, Enterococcus." /> } route="IV" notes="q24-48h. Monitor levels." /> } route="IV" notes="If meningitis or gram-neg concern." /> } route="IV q8h" notes="HSV risk: maternal lesions, vesicles, seizures, CSF pleocytosis." /> } {age === 'infant' && <> } route="IV / IM" notes="q24h (100 mg/kg/day divided q12h for meningitis). Avoid <28 d if hyperbilirubinemia." /> } route="IV" notes="If <6 wk: add for Listeria coverage." /> } route="IV" notes="If severe / MRSA risk / meningitis." /> } route="IV q8h" notes="<6 wk with suspicion of HSV." /> } {age === 'child' && <> } route="IV" notes="q24h (100 mg/kg/day divided for meningitis)." /> } route="IV" notes="q6h. If severe, indwelling line, or MRSA prevalence >10%." /> } route="IV" notes="If intra-abdominal / neutropenic." /> } route="IV" notes="Adjunct for toxic shock syndrome (toxin suppression)." /> } route="IV q8h" notes="If HSV CNS concern." /> } )}

First-hour bundle (SSC Peds 2020)

0-5 min — Recognize
Screen, sepsis huddle/activation, ABCs, O₂ to SpO₂ >94%, warm.
5-15 min — Access & labs
Two IVs or IO. Draw blood cx (ideally before abx), lactate, CBC, CMP, coags, blood gas, glucose. UA + culture. Source-specific cultures.
15-30 min — Fluids
{valid ? <>NS or LR {bolus} mL bolus (20 mL/kg) over 5-10 min. : <>NS/LR 10-20 mL/kg bolus over 5-10 min.} Reassess HR, perfusion, lungs, liver. Repeat up to 40-60 mL/kg; stop if crackles/hepatomegaly.
30-60 min — Antibiotics + reassess
Broad-spectrum empiric abx within 1 hour (≤1 h in septic shock). Recheck lactate, perfusion.
>60 min — Fluid-refractory shock
Start vasoactive (epinephrine 0.05-0.3 mcg/kg/min cold / norepinephrine 0.05-0.3 mcg/kg/min warm). Central/IO access. Stress-dose hydrocortisone {valid ? <>{f(2, 100)!.value} mg IV (2 mg/kg, max 100 mg) : '2 mg/kg IV (max 100 mg)'} if catecholamine-resistant. ICU.

Resuscitation targets

Normal mentation · Cap refill ≤2 s · Warm extremities · Strong peripheral pulses · UOP ≥1 mL/kg/hr · MAP ≥5th %ile for age (>65 mmHg adolescent) · SpO₂ ≥94% · Lactate trending down.
Phoenix Sepsis Criteria (Schlapbach et al., JAMA 2024) · Surviving Sepsis Campaign Pediatric 2020 · AAP pediatric sepsis guidance.
); } // ── Burns ─────────────────────────────────────────────────── // Lund-Browder age-adjusted region percentages ported VERBATIM from // public/js/bedside/burns.js:10-30. const LUND_BROWDER: Array<{ key: string; label: string; vals: [number, number, number, number, number]; ageSensitive?: boolean }> = [ { key: 'head', label: 'Head', vals: [18, 13, 11, 9, 7], ageSensitive: true }, { key: 'neck', label: 'Neck', vals: [2, 2, 2, 2, 2] }, { key: 'ant_trunk', label: 'Anterior trunk', vals: [13, 13, 13, 13, 13] }, { key: 'post_trunk', label: 'Posterior trunk', vals: [13, 13, 13, 13, 13] }, { key: 'r_buttock', label: 'Right buttock', vals: [2.5, 2.5, 2.5, 2.5, 2.5] }, { key: 'l_buttock', label: 'Left buttock', vals: [2.5, 2.5, 2.5, 2.5, 2.5] }, { key: 'genital', label: 'Genitalia', vals: [1, 1, 1, 1, 1] }, { key: 'r_uparm', label: 'R upper arm', vals: [4, 4, 4, 4, 4] }, { key: 'l_uparm', label: 'L upper arm', vals: [4, 4, 4, 4, 4] }, { key: 'r_forearm', label: 'R forearm', vals: [3, 3, 3, 3, 3] }, { key: 'l_forearm', label: 'L forearm', vals: [3, 3, 3, 3, 3] }, { key: 'r_hand', label: 'R hand', vals: [2.5, 2.5, 2.5, 2.5, 2.5] }, { key: 'l_hand', label: 'L hand', vals: [2.5, 2.5, 2.5, 2.5, 2.5] }, { key: 'r_thigh', label: 'R thigh', vals: [5.5, 8, 8.5, 9, 9.5], ageSensitive: true }, { key: 'l_thigh', label: 'L thigh', vals: [5.5, 8, 8.5, 9, 9.5], ageSensitive: true }, { key: 'r_leg', label: 'R lower leg', vals: [5, 5.5, 6, 6.5, 7], ageSensitive: true }, { key: 'l_leg', label: 'L lower leg', vals: [5, 5.5, 6, 6.5, 7], ageSensitive: true }, { key: 'r_foot', label: 'R foot', vals: [3.5, 3.5, 3.5, 3.5, 3.5] }, { key: 'l_foot', label: 'L foot', vals: [3.5, 3.5, 3.5, 3.5, 3.5] }, ]; const AGE_BANDS: Array<{ id: 'infant' | 'young' | 'child' | 'adol' | 'adult'; label: string }> = [ { id: 'infant', label: 'Infant (<1 y)' }, { id: 'young', label: 'Young child (1-5 y)' }, { id: 'child', label: 'Child (5-10 y)' }, { id: 'adol', label: 'Adolescent (10-15 y)' }, { id: 'adult', label: 'Adult (>15 y)' }, ]; export function BurnsPanel() { const [weight, setWeight] = useState(''); const [ageBand, setAgeBand] = useState<'infant' | 'young' | 'child' | 'adol' | 'adult'>('young'); const [override, setOverride] = useState(''); const [pct, setPct] = useState>({}); const ageIdx = AGE_BANDS.findIndex((a) => a.id === ageBand); const computedTbsa = LUND_BROWDER.reduce( (sum, r) => sum + r.vals[ageIdx] * Math.min(100, Math.max(0, pct[r.key] ?? 0)) / 100, 0, ); const tbsa = override.trim() ? Number(override) : Math.round(computedTbsa * 10) / 10; const wt = Number.parseFloat(weight); const validWt = Number.isFinite(wt) && wt > 0; const validTbsa = Number.isFinite(tbsa) && tbsa > 0; const total = validWt && validTbsa ? Math.round(4 * wt * tbsa) : 0; const first8 = Math.round(total / 2); const rateFirst = Math.round(first8 / 8); const next16 = total - first8; const rateNext = Math.round(next16 / 16); const maint = validWt ? Math.round(wt <= 10 ? wt * 4 : wt <= 20 ? 40 + (wt - 10) * 2 : 60 + (wt - 20)) : 0; return (

Burns — Lund-Browder + Parkland

setWeight(e.target.value)} data-testid="burn-weight" />
setOverride(e.target.value)} placeholder={validTbsa ? String(tbsa) : 'auto'} data-testid="burn-tbsa" />

Body parts — % of each region burned (2° or deeper)

{LUND_BROWDER.map((r) => { const max = r.vals[ageIdx]; return (
setPct({ ...pct, [r.key]: Number(e.target.value) })} data-testid={'burn-region-' + r.key} /> %
); })}
{validTbsa &&
Computed TBSA: {tbsa}%
} {!validWt &&

Enter weight (kg) to see Parkland + maintenance fluids.

} {!validTbsa && validWt &&

Enter % per region or override TBSA to compute fluids.

} {validWt && validTbsa && ( <>
Burn fluid resuscitation — {wt} kg, {tbsa}% TBSA (2° or deeper)
Parkland formula: 4 mL × kg × %TBSA = {total} mL LR over 24 hours
First 8 h (from time of burn): {first8} mL (~{rateFirst} mL/hr)
Next 16 h: {next16} mL (~{rateNext} mL/hr)
Plus maintenance (4-2-1): {maint} mL/hr (D5 ½NS ± 20 mEq KCl/L once UOP established). Consider dextrose in children <30 kg.
Titrate to UOP: target 1-2 mL/kg/hr (infants / children), 0.5-1 mL/kg/hr (adolescents). Clinical response trumps formula.
)}

Other pearls

Rule of palm: Patient's palm + fingers ≈ 1% TBSA — good for scattered burns.
First-degree burns DO NOT count toward TBSA or Parkland.
Analgesia: Morphine 0.05-0.1 mg/kg IV q2h, or fentanyl 1-2 mcg/kg IV q30-60 min.
Tetanus prophylaxis if indicated. Tdap/Td ± TIG.

Burn center referral (ABA)

Partial-thickness >10% TBSA · any full-thickness · face/hands/feet/genital/perineum/major joints · electrical/chemical/inhalation · associated trauma · significant comorbidities · pediatric burns in non-pediatric center.
ABA Advanced Burn Life Support 2018 · Parkland formula: Baxter 1968 · Lund-Browder 1944.
); }