Hyponatremic seizure, cut off of sodium
hyponatremia seizure sodium threshold
| Scenario | Seizure Risk |
|---|---|
| Acute hyponatremia (< 48 h) | Seizures can occur even at Na > 120 mEq/L |
| Chronic hyponatremia (> 48 h) | Much less risk; seizures rare unless Na < 120 mEq/L |
| Profound hyponatremia (< 125 mEq/L) | Nausea, vomiting, confusion, seizures (5%), coma |
| Grade | Serum Na | Typical Symptoms |
|---|---|---|
| Mild | 130-135 mEq/L | Often asymptomatic |
| Moderate | 125-129 mEq/L | Nausea, headache, confusion |
| Profound / Severe | < 125 mEq/L | Seizures (~5%), coma, herniation risk |
| Patient Type | Max Correction Rate |
|---|---|
| High-risk (chronic, malnourished, alcoholic, hypokalemia) | 6 mEq/L per 24 hours |
| Low-risk patients | 12 mEq/L per 24 hours |
| Acute symptomatic (seizures) | Rapid initial 5 mEq/L rise is safe and necessary |
Create a quick-reference guide for hyponatremia management
mkdir -p /tmp/workspace/hyponatremia-guide && ls /tmp/workspace/hyponatremia-guide/
~/hyponatremia-guide/build_guide.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import PageBreak
from reportlab.lib.colors import HexColor
OUTPUT = "/tmp/workspace/hyponatremia-guide/Hyponatremia_Quick_Reference.pdf"
# -- Colour palette --
NAVY = HexColor("#1A3A5C")
TEAL = HexColor("#0E7490")
AMBER = HexColor("#B45309")
RED = HexColor("#B91C1C")
GREEN = HexColor("#166534")
LGREY = HexColor("#F1F5F9")
MGREY = HexColor("#CBD5E1")
WHITE = colors.white
BLACK = colors.black
LBLUE = HexColor("#DBEAFE")
LGREEN = HexColor("#DCFCE7")
LRED = HexColor("#FEE2E2")
LYELLOW = HexColor("#FEF9C3")
LORANGE = HexColor("#FFEDD5")
PAGE_W, PAGE_H = A4
MARGIN = 1.5*cm
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=MARGIN, leftMargin=MARGIN,
topMargin=1.8*cm, bottomMargin=1.5*cm,
title="Hyponatremia Quick Reference Guide",
author="Orris Medical Reference",
)
styles = getSampleStyleSheet()
def sty(name, **kw):
s = ParagraphStyle(name, parent=styles["Normal"], **kw)
return s
H0 = sty("H0", fontSize=20, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_CENTER, leading=26, spaceAfter=0)
H1 = sty("H1", fontSize=12, textColor=WHITE, fontName="Helvetica-Bold",
leading=16, spaceAfter=2)
H2 = sty("H2", fontSize=10, textColor=NAVY, fontName="Helvetica-Bold",
leading=14, spaceAfter=3, spaceBefore=4)
BODY = sty("BODY", fontSize=8.5, textColor=BLACK, leading=12,
spaceAfter=2, fontName="Helvetica")
BODY_SM = sty("BODY_SM", fontSize=7.8, textColor=BLACK, leading=11,
spaceAfter=1, fontName="Helvetica")
BOLD_SM = sty("BOLD_SM", fontSize=8, textColor=BLACK, fontName="Helvetica-Bold",
leading=11, spaceAfter=1)
CAPTION = sty("CAPTION", fontSize=7, textColor=HexColor("#475569"),
leading=10, fontName="Helvetica-Oblique", alignment=TA_CENTER)
WARN = sty("WARN", fontSize=8, textColor=RED, fontName="Helvetica-Bold",
leading=11, spaceAfter=2)
FOOTER = sty("FOOTER", fontSize=6.5, textColor=HexColor("#64748B"),
leading=9, fontName="Helvetica", alignment=TA_CENTER)
CONTENT_W = PAGE_W - 2*MARGIN
def header_box(text, bg=NAVY, fg=WHITE, pad=8):
tbl = Table([[Paragraph(text, sty("hdr", fontSize=11, textColor=fg,
fontName="Helvetica-Bold", leading=14, alignment=TA_CENTER))]],
colWidths=[CONTENT_W])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), pad),
("BOTTOMPADDING", (0,0), (-1,-1), pad),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [4, 4, 4, 4]),
]))
return tbl
def section_header(text, bg=TEAL):
return header_box(text, bg=bg)
def two_col(left, right, lw=None, rw=None, vpad=4):
lw = lw or CONTENT_W * 0.48
rw = rw or CONTENT_W * 0.48
gap = CONTENT_W - lw - rw
tbl = Table([[left, right]], colWidths=[lw, rw])
tbl.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 tbl
def colored_cell(text, bg=LGREY, style=None):
p = Paragraph(text, style or BODY_SM)
t = Table([[p]], colWidths=["100%"])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
]))
return t
def make_table(data, col_widths, header_bg=NAVY, row_bg1=WHITE, row_bg2=LGREY,
header_fg=WHITE, fontsize=8):
header = data[0]
rows = data[1:]
hdr_style = sty("thdr", fontSize=fontsize, textColor=header_fg,
fontName="Helvetica-Bold", leading=fontsize+3, alignment=TA_CENTER)
cell_style = sty("tcell", fontSize=fontsize-0.5, textColor=BLACK,
fontName="Helvetica", leading=fontsize+2, alignment=TA_LEFT)
cell_center = sty("tcc", fontSize=fontsize-0.5, textColor=BLACK,
fontName="Helvetica", leading=fontsize+2, alignment=TA_CENTER)
tdata = [[Paragraph(str(h), hdr_style) for h in header]]
for i, row in enumerate(rows):
tdata.append([Paragraph(str(c), cell_style) for c in row])
tbl = Table(tdata, colWidths=col_widths, repeatRows=1)
ts = [
("BACKGROUND", (0,0), (-1,0), header_bg),
("GRID", (0,0), (-1,-1), 0.4, MGREY),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]
for i in range(1, len(tdata)):
bg = row_bg1 if i % 2 == 0 else row_bg2
ts.append(("BACKGROUND", (0,i), (-1,i), bg))
tbl.setStyle(TableStyle(ts))
return tbl
story = []
# =====================================================================
# TITLE BANNER
# =====================================================================
title_tbl = Table(
[[Paragraph("HYPONATREMIA", sty("t1", fontSize=24, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=30)),
Paragraph("Quick Reference Guide", sty("t2", fontSize=13, textColor=HexColor("#BAE6FD"),
fontName="Helvetica", alignment=TA_CENTER, leading=18))]],
colWidths=[CONTENT_W * 0.5, CONTENT_W * 0.5]
)
title_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("TOPPADDING", (0,0), (-1,-1), 14),
("BOTTOMPADDING", (0,0), (-1,-1), 14),
("LEFTPADDING", (0,0), (-1,-1), 10),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(title_tbl)
story.append(Spacer(1, 4*mm))
subtitle_data = [
[Paragraph("For Emergency, ICU & General Medicine Clinicians", sty("sub",
fontSize=8.5, textColor=HexColor("#475569"), fontName="Helvetica-Oblique",
alignment=TA_CENTER))]
]
sub_tbl = Table(subtitle_data, colWidths=[CONTENT_W])
sub_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LGREY),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
]))
story.append(sub_tbl)
story.append(Spacer(1, 5*mm))
# =====================================================================
# SECTION 1 — DEFINITION & CLASSIFICATION
# =====================================================================
story.append(KeepTogether([
section_header("1. DEFINITION & SEVERITY CLASSIFICATION"),
Spacer(1, 3*mm),
]))
classify_data = [
["Grade", "Serum Na+", "Common Symptoms"],
["Mild", "130–135 mEq/L", "Often asymptomatic; subtle cognitive changes"],
["Moderate", "125–129 mEq/L", "Nausea (44-49%), headache (27%), confusion (14-30%), gait disturbance (31%)"],
["Severe / Profound", "< 125 mEq/L", "Vomiting (27-30%), seizures (~5%), coma, brainstem herniation, death"],
]
story.append(make_table(classify_data,
[CONTENT_W*0.14, CONTENT_W*0.20, CONTENT_W*0.66],
header_bg=NAVY))
story.append(Spacer(1, 2*mm))
story.append(Paragraph(
"<b>Duration matters:</b> Acute (<48 h) vs Chronic (>48 h) — when duration unknown, assume <b>chronic</b>.",
BODY_SM))
story.append(Spacer(1, 5*mm))
# =====================================================================
# SECTION 2 — PATHOPHYSIOLOGY SNAPSHOT
# =====================================================================
story.append(KeepTogether([
section_header("2. PATHOPHYSIOLOGY SNAPSHOT", bg=TEAL),
Spacer(1, 3*mm),
]))
path_data = [
["Acute (<48 h)", "Chronic (>48 h)"],
[
"Extracellular Na+ falls\n→ Plasma becomes hypotonic\n→ Water floods brain astrocytes\n→ Cerebral edema, raised ICP\n→ Seizures / herniation even at Na >120",
"Astrocytes export osmolytes (taurine, inositol)\n→ Intracellular osmolality falls\n→ Less water influx, less edema\n→ Symptoms occur at lower Na levels\n→ Seizures much less frequent"
]
]
path_tbl = Table(
[[Paragraph("<b>Acute (<48 h)</b>", sty("ph", fontSize=9, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_CENTER, leading=12)),
Paragraph("<b>Chronic (>48 h)</b>", sty("ph2", fontSize=9, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_CENTER, leading=12))],
[Paragraph("Extracellular Na<sup>+</sup> falls → plasma hypotonic → water floods brain astrocytes → cerebral edema, raised ICP → seizures/herniation possible even at Na > 120 mEq/L",
BODY_SM),
Paragraph("Astrocytes export osmolytes (taurine, inositol) → intracellular osmolality falls → less water influx → less edema → symptoms occur at lower Na levels → seizures much less frequent",
BODY_SM)]],
colWidths=[CONTENT_W*0.49, CONTENT_W*0.49]
)
path_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), RED),
("BACKGROUND", (1,0), (1,0), GREEN),
("BACKGROUND", (0,1), (0,1), HexColor("#FFF1F2")),
("BACKGROUND", (1,1), (1,1), LGREEN),
("GRID", (0,0), (-1,-1), 0.4, MGREY),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(path_tbl)
story.append(Spacer(1, 5*mm))
# =====================================================================
# SECTION 3 — DIAGNOSTIC APPROACH
# =====================================================================
story.append(KeepTogether([
section_header("3. DIAGNOSTIC APPROACH (4-Step Framework)", bg=HexColor("#1E3A5F")),
Spacer(1, 3*mm),
]))
steps = [
("Step 1", "Scan for diagnostic clues",
"Hyperglycemia → hyperglycemic hyponatremia | Thiazide use → diuretic-induced | "
"Post-marathon → EAH | Hyperkalemia → adrenal insufficiency or renal failure | "
"Very low Uosm → psychogenic polydipsia / beer potomania | Normal osmolality → pseudohyponatremia"),
("Step 2", "Assess volume status",
"<b>Hypervolemic:</b> HF, cirrhosis, nephrotic syndrome, renal failure (edema, JVD)<br/>"
"<b>Hypovolemic:</b> hypotension, orthostasis, diarrhea/vomiting, diuretics<br/>"
"<b>Euvolemic:</b> neither hyper- nor hypovolemic → proceed to Step 3"),
("Step 3", "Urine Na+ in apparent euvolemia",
"UNa < 20-30 mEq/L → occult <b>hypovolemia</b> (avid renal Na retention)<br/>"
"UNa > 20-30 mEq/L → true <b>euvolemia</b> → proceed to Step 4"),
("Step 4", "Rule out endocrine before diagnosing SIADH",
"Exclude <b>hypothyroidism</b> (TSH) and <b>adrenal insufficiency</b> (morning cortisol/ACTH stim)<br/>"
"If normal → diagnose <b>SIADH</b>"),
]
for num, title, text in steps:
row_tbl = Table([[
Paragraph(num, sty("snum", fontSize=9, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_CENTER, leading=12)),
Paragraph(f"<b>{title}</b><br/>{text}", BODY_SM)
]], colWidths=[CONTENT_W*0.09, CONTENT_W*0.91])
row_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,-1), TEAL),
("BACKGROUND", (1,0), (1,-1), WHITE),
("GRID", (0,0), (-1,-1), 0.4, MGREY),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
]))
story.append(row_tbl)
story.append(Spacer(1, 1*mm))
story.append(Spacer(1, 3*mm))
# SIADH box
siadh_criteria = [
["SIADH Diagnostic Criteria"],
["1. Serum hypo-osmolality (<275 mOsm/kg)"],
["2. Urine osmolality inappropriately elevated (>100–200 mOsm/kg)"],
["3. Urine Na+ elevated (>20–30 mEq/L) with adequate Na intake"],
["4. Clinical euvolemia (no edema, no orthostasis)"],
["5. Normal renal, adrenal, thyroid, cardiac, hepatic function"],
["6. Not on diuretics"],
]
siadh_tbl = Table(
[[Paragraph("<b>SIADH Diagnostic Criteria</b>", sty("sh", fontSize=9, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=13))]]+
[[Paragraph(f"{'• '+r[0]}", BODY_SM)] for r in siadh_criteria[1:]],
colWidths=[CONTENT_W]
)
siadh_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), HexColor("#0369A1")),
("BACKGROUND", (0,1), (-1,-1), LBLUE),
("GRID", (0,0), (-1,-1), 0.3, HexColor("#BAE6FD")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 8),
]))
story.append(siadh_tbl)
story.append(Spacer(1, 5*mm))
# =====================================================================
# SECTION 4 — TREATMENT
# =====================================================================
story.append(KeepTogether([
section_header("4. TREATMENT", bg=HexColor("#7C3AED")),
Spacer(1, 3*mm),
]))
tx_data = [
["Presentation", "First-line Treatment", "Key Notes"],
["<b>Severe symptoms</b>\n(seizures, coma, vomiting, respiratory arrest)",
"3% Hypertonic Saline IV\n• Adult: 100 mL bolus (repeat x2 if needed)\n• Peds: 3–5 mL/kg over 15–30 min\nTarget: raise Na by 5 mEq/L",
"Raising Na by 5 mEq/L typically aborts seizures. Target Na >124 mEq/L. Do NOT wait to confirm Na before treating."],
["<b>Moderate symptoms</b>\n(nausea, confusion, headache)",
"3% NaCl at low rate 0.5–1 mL/kg/h\nOR fluid restriction if SIADH",
"Correct slower than acute. Monitor Na q1–4h."],
["<b>Mild / Asymptomatic</b>\nChronic hyponatremia",
"Treat underlying cause:\n• Hypovolemic → isotonic saline\n• Hypervolemic (HF/cirrhosis) → fluid restriction ± loop diuretic\n• SIADH → fluid restriction, salt tabs, vaptans (tolvaptan/conivaptan)",
"Avoid rapid correction. No active therapy within 24h of hypertonic saline."],
["<b>Exercise-Associated\nHyponatremia (EAH)</b>",
"If symptomatic: 3% NaCl bolus 100 mL (adult)\nDo NOT give hypotonic or isotonic IV fluids!",
"Develops acutely; aggressive correction is safe. Symptoms at Na 125–130 mEq/L possible."],
]
story.append(make_table(tx_data,
[CONTENT_W*0.22, CONTENT_W*0.38, CONTENT_W*0.40],
header_bg=HexColor("#7C3AED"),
row_bg1=WHITE, row_bg2=HexColor("#F5F3FF"),
fontsize=7.8))
story.append(Spacer(1, 3*mm))
# Hypertonic saline note
hs_box = Table([[
Paragraph("Isotonic (0.9%) saline", sty("hsb", fontSize=8.5, textColor=NAVY,
fontName="Helvetica-Bold", leading=12)),
Paragraph("may be used for mild hyponatremia (esp. hypovolemic), but account for additional fluid load. "
"Loop diuretics (furosemide 20 mg IV) may be added alongside saline infusions to enhance free-water excretion.",
BODY_SM)
]], colWidths=[CONTENT_W*0.28, CONTENT_W*0.72])
hs_box.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LYELLOW),
("GRID", (0,0), (-1,-1), 0.3, HexColor("#FDE68A")),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
]))
story.append(hs_box)
story.append(Spacer(1, 5*mm))
# =====================================================================
# SECTION 5 — CORRECTION RATE LIMITS
# =====================================================================
story.append(KeepTogether([
section_header("5. SAFE CORRECTION RATE LIMITS", bg=AMBER),
Spacer(1, 3*mm),
]))
rate_data = [
["Patient Category", "Max Correction Rate", "Rationale"],
["<b>Standard (low-risk)</b>", "<b>8–12 mEq/L per 24 h</b>\n(max 18 mEq/L per 48 h)",
"Prevents ODS in most patients"],
["<b>High-risk for ODS</b>\n(alcohol abuse, malnutrition, Na <105 mEq/L, hypokalemia, liver disease, diuretic-induced)",
"<b>6 mEq/L per 24 h</b>", "These patients are at greatest risk of demyelination"],
["<b>Acute symptomatic\n(seizure / herniation)</b>",
"Rapid 5 mEq/L rise is <b>safe and necessary</b>\nto abort seizure, then revert to safe rate",
"Life-threatening cerebral edema overrides the ODS risk temporarily"],
["<b>Acute EAH</b>",
"Aggressive correction safe (developed rapidly)",
"Rapid onset = safe to correct rapidly"],
]
story.append(make_table(rate_data,
[CONTENT_W*0.30, CONTENT_W*0.30, CONTENT_W*0.40],
header_bg=AMBER, row_bg2=LORANGE, fontsize=7.8))
story.append(Spacer(1, 2*mm))
story.append(Paragraph(
"<b>If correction is too fast:</b> Administer desmopressin (DDAVP) and D5W to slow or reverse the rate of sodium rise.",
BODY_SM))
story.append(Spacer(1, 5*mm))
# =====================================================================
# SECTION 6 — ODS
# =====================================================================
story.append(KeepTogether([
section_header("6. OSMOTIC DEMYELINATION SYNDROME (ODS)", bg=RED),
Spacer(1, 3*mm),
]))
ods_left = [
Paragraph("<b>Mechanism</b>", H2),
Paragraph("In chronic hyponatremia, astrocytes lower intracellular osmolality by exporting osmolytes. "
"Rapid correction renders serum hypertonic vs. astrocytes → water exits cells → "
"cytoskeletal damage → oligodendrocyte death → demyelination (pons most affected).", BODY_SM),
Spacer(1, 3*mm),
Paragraph("<b>Onset</b>", H2),
Paragraph("Symptoms appear <b>2–6 days</b> after overcorrection. MRI may not show lesions for <b>up to 4 weeks</b>.", BODY_SM),
Spacer(1, 3*mm),
Paragraph("<b>Symptoms</b>", H2),
Paragraph("Spastic quadriparesis · pseudobulbar palsy (dysarthria, dysphagia, diplopia) · "
"coma · movement disorders · seizures · ataxia · behavioral disorders · death", BODY_SM),
]
ods_right = [
Paragraph("<b>Risk Factors</b>", H2),
]
rf_items = [
"Na+ <105 mEq/L (virtually always <120)",
"Alcohol abuse",
"Malnutrition",
"Hypokalemia",
"Advanced liver disease",
"Diuretic-associated hyponatremia",
"Treated cortisol deficiency",
"Vaptan (tolvaptan) treatment",
]
for rf in rf_items:
ods_right.append(Paragraph(f"• {rf}", BODY_SM))
ods_right.append(Spacer(1, 3*mm))
ods_right.append(Paragraph("<b>Prevention</b>", H2))
ods_right.append(Paragraph(
"• Keep correction <6–12 mEq/L/24h<br/>"
"• DDAVP + D5W to reverse if overcorrected<br/>"
"• Consider prophylactic DDAVP + 3% NaCl in very high-risk patients",
BODY_SM))
ods_tbl = Table([[ods_left, ods_right]], colWidths=[CONTENT_W*0.49, CONTENT_W*0.49])
ods_tbl.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("BACKGROUND", (0,0), (0,0), HexColor("#FFF1F2")),
("BACKGROUND", (1,0), (1,0), LRED),
("BOX", (0,0), (-1,-1), 0.5, MGREY),
("INNERGRID", (0,0), (-1,-1), 0.3, MGREY),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 7),
("RIGHTPADDING", (0,0), (-1,-1), 7),
]))
story.append(ods_tbl)
story.append(Spacer(1, 5*mm))
# =====================================================================
# SECTION 7 — SODIUM CUTOFF & SEIZURE ALERT
# =====================================================================
story.append(KeepTogether([
section_header("7. SEIZURE THRESHOLD & SODIUM CUTOFFS", bg=HexColor("#B91C1C")),
Spacer(1, 3*mm),
]))
cutoff_data = [
["Na+ Level", "Risk", "Action"],
["130–135 mEq/L", "Low — usually asymptomatic", "Investigate cause; treat underlying condition"],
["125–129 mEq/L", "Moderate — nausea, headache, confusion", "Fluid restriction / treat cause; monitor closely"],
["120–124 mEq/L", "High — seizures possible\n(esp. if acute onset)", "Consider 3% NaCl if symptomatic; urgent evaluation"],
["<120 mEq/L", "<b>CRITICAL — seizures likely\n(classical cutoff)</b>", "<b>3% NaCl immediately</b>; ICU monitoring"],
["<115 mEq/L", "<b>EMERGENCY — herniation, death risk</b>", "<b>Emergent treatment; neurology/ICU consult</b>"],
]
story.append(make_table(cutoff_data,
[CONTENT_W*0.20, CONTENT_W*0.35, CONTENT_W*0.45],
header_bg=RED, row_bg2=LRED, fontsize=8))
story.append(Spacer(1, 2*mm))
alert_box = Table([[
Paragraph("⚠ ACUTE ONSET CAVEAT:", sty("alert", fontSize=8.5, textColor=RED,
fontName="Helvetica-Bold", leading=12)),
Paragraph("In acute hyponatremia (<48 h), seizures and herniation can occur at Na >120 mEq/L "
"(even 125–130 in EAH). The absolute value is less important than the <b>rate of fall</b>.",
BODY_SM)
]], colWidths=[CONTENT_W*0.28, CONTENT_W*0.72])
alert_box.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LRED),
("BOX", (0,0), (-1,-1), 1, RED),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 8),
]))
story.append(alert_box)
story.append(Spacer(1, 5*mm))
# =====================================================================
# SECTION 8 — MONITORING
# =====================================================================
story.append(KeepTogether([
section_header("8. MONITORING PROTOCOL", bg=HexColor("#065F46")),
Spacer(1, 3*mm),
]))
mon_items = [
"Check serum Na+ <b>every 1–4 hours</b> during active treatment with hypertonic saline",
"Monitor ECF volume status alongside serum Na+",
"Track urine Na+ and urine osmolality to guide therapy",
"Document total Na+ rise per 24h and per 48h — alert if approaching limits",
"If Na+ corrects faster than target, <b>immediately give DDAVP 2 mcg IV + D5W</b> to arrest the rise",
"Transition from IV to oral management when patient is stable and Na+ > 125 mEq/L",
]
mon_tbl = Table(
[[Paragraph(f"• {item}", BODY_SM)] for item in mon_items],
colWidths=[CONTENT_W]
)
mon_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LGREEN),
("GRID", (0,0), (-1,-1), 0.3, HexColor("#A7F3D0")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 8),
]))
story.append(mon_tbl)
story.append(Spacer(1, 5*mm))
# =====================================================================
# SECTION 9 — SPECIAL POPULATIONS
# =====================================================================
story.append(KeepTogether([
section_header("9. SPECIAL POPULATIONS & CAUSES", bg=HexColor("#6B21A8")),
Spacer(1, 3*mm),
]))
sp_data = [
["Population / Cause", "Key Features", "Treatment Pearl"],
["SIADH\n(many causes: malignancy, CNS, pulmonary, drugs)",
"Euvolemic; elevated UNa; concentrated urine; exclude endocrine",
"Fluid restriction ± salt tabs; vaptans (tolvaptan) for resistant cases; treat underlying cause"],
["Heart Failure / Cirrhosis / Nephrotic Syndrome",
"Hypervolemic; edema; JVD; low UNa (<10); avid Na retention",
"Fluid restriction + loop diuretics; treat underlying condition; vaptans in select cases"],
["Diuretic-induced\n(thiazides most common)",
"Hypovolemic; low UNa after diuretic stopped; high ODS risk",
"Stop diuretic; cautious saline replacement; high ODS risk — max 6 mEq/24h"],
["Adrenal Insufficiency",
"Euvolemic/hypovolemic; hyperkalemia; low cortisol; elevated ACTH",
"Hydrocortisone IV; Na corrects with glucocorticoid replacement"],
["Hypothyroidism",
"Euvolemic; TSH elevated; myxedema features",
"Thyroid hormone replacement; Na corrects slowly"],
["Exercise-Associated\nHyponatremia (EAH)",
"Acute onset during/after endurance event; weight gain; brain edema risk",
"3% NaCl if symptomatic; NO hypotonic fluids; aggressive correction safe"],
["DDAVP for enuresis\n(esp. children)",
"Acute hyponatremia; Na range 104–130 at seizure onset",
"Stop DDAVP; fluid restriction; 3% NaCl if seizures"],
["Psychogenic polydipsia / beer potomania / Ecstasy",
"Very low Uosm; water intoxication; acute",
"Fluid restriction; water intake cessation; 3% NaCl if severe symptoms"],
]
story.append(make_table(sp_data,
[CONTENT_W*0.22, CONTENT_W*0.38, CONTENT_W*0.40],
header_bg=HexColor("#6B21A8"),
row_bg2=HexColor("#F5F3FF"),
fontsize=7.5))
story.append(Spacer(1, 5*mm))
# =====================================================================
# SECTION 10 — 3% NaCl QUICK REFERENCE
# =====================================================================
story.append(KeepTogether([
section_header("10. 3% HYPERTONIC SALINE — DOSING AT A GLANCE", bg=HexColor("#0F4C81")),
Spacer(1, 3*mm),
]))
hs_data = [
["Indication", "Dose", "Rate / Duration", "Target"],
["Seizure / Severe encephalopathy (Adult)",
"100 mL 3% NaCl IV bolus\n(repeat up to 3×)",
"Over 10–15 min per bolus",
"Raise Na by 5 mEq/L to abort seizure; then maintain <12 mEq/L rise per 24h"],
["Seizure / Severe encephalopathy (Pediatric)",
"3–5 mL/kg 3% NaCl IV",
"Over 15–30 min",
"Seizure cessation; target Na >124 mEq/L"],
["Moderate symptoms (Adult)",
"3% NaCl 0.5–1 mL/kg/h",
"Continuous infusion",
"<8–12 mEq/L rise per 24h; frequent Na monitoring"],
["EAH — symptomatic (Adult)",
"100 mL 3% NaCl bolus",
"Over 10 min; repeat if needed",
"Symptom resolution; correction rate not restricted given acute onset"],
]
story.append(make_table(hs_data,
[CONTENT_W*0.25, CONTENT_W*0.25, CONTENT_W*0.22, CONTENT_W*0.28],
header_bg=HexColor("#0F4C81"),
row_bg2=LBLUE,
fontsize=7.8))
story.append(Spacer(1, 5*mm))
# =====================================================================
# FOOTER / REFERENCES
# =====================================================================
HRFlowable(width=CONTENT_W, thickness=0.5, color=MGREY)
story.append(HRFlowable(width=CONTENT_W, thickness=0.5, color=MGREY))
story.append(Spacer(1, 2*mm))
story.append(Paragraph(
"<b>Sources:</b> Symptom to Diagnosis 4e · Tintinalli's Emergency Medicine 9e · Rosen's Emergency Medicine 9e · "
"Miller's Anesthesia 10e · Harriet Lane Handbook 23e · Barash Clinical Anesthesia 9e · "
"Harrison's Principles of Internal Medicine 22e · Brenner & Rector's The Kidney · "
"National Kidney Foundation Primer on Kidney Diseases 8e",
FOOTER))
story.append(Spacer(1, 1*mm))
story.append(Paragraph(
"This guide is for educational reference only. Clinical decisions must be made by qualified healthcare professionals.",
FOOTER))
# =====================================================================
# BUILD
# =====================================================================
doc.build(story)
print(f"PDF saved to {OUTPUT}")
cd /tmp/workspace/hyponatremia-guide && python build_guide.py 2>&1
ls -lh /tmp/workspace/hyponatremia-guide/Hyponatremia_Quick_Reference.pdf
Hyponatremia Quick Reference
PDF Document · PDF
| Section | Content |
|---|---|
| 1. Classification | Mild / Moderate / Severe grades with Na+ thresholds and symptoms |
| 2. Pathophysiology | Acute vs Chronic side-by-side comparison |
| 3. Diagnostic Approach | 4-step framework (clues → volume status → urine Na → endocrine) + SIADH criteria box |
| 4. Treatment | Severe / Moderate / Mild / EAH management with specific regimens |
| 5. Correction Rate Limits | Standard (12 mEq/24h) vs High-risk (6 mEq/24h) vs Seizure (5 mEq rapid bolus) |
| 6. ODS | Mechanism, timing, risk factors, prevention and reversal |
| 7. Seizure Threshold | Color-coded Na+ cutoff table from 130 → <115, plus acute-onset caveat |
| 8. Monitoring Protocol | Frequency of checks, when to give DDAVP rescue |
| 9. Special Populations | SIADH, HF/cirrhosis, diuretics, adrenal, hypothyroidism, EAH, DDAVP, polydipsia |
| 10. 3% NaCl Dosing | Adult vs pediatric bolus and infusion doses with targets |