Chronic kidney disease (CKD): management CKD encompasses a range of disease from mild disease without progression to ad- vanced, symptomatic disease requiring renal replacement. Management of CKD6,8 requires: 1 Appropriate referral to nephrology. 2 Treatment to slow renal disease progression. 3 Treatment of renal complications of CKD. 4 Treatment of other complications of CKD. 5 Preparation for renal replacement therapy (dialysis/transplantation) (p306). Referral to nephrology Consider referral for: • stage G4 and G5 CKD (table 7.5) • moderate proteinuria A:CR >70mg/mmol unless due to DM and already treated • proteinuria A:CR >30mg/mmol with haematuria • declining eGFR: • eGFR by ≥25% + GFR category (table 7.5) • sustained eGFR ≥15% within 12 months • BP poorly controlled despite ≥4 antihypertensive drugs at therapeutic dose • known or suspected rare or genetic cause of CKD. Treatment to slow renal disease progression BP: Target systolic BP is <140mmHg (range 120–139mmHg) and diastolic <90mmHg. If DM or A:CR >70 then systolic target is <130mmHg (range 120–129) and diastolic <80mmHg. Renin–angiotensin system: Off er treatment with a renin–angiotensin system an- tagonist (ACE-i, ARB) to: • DM and A:CR >3mg/mmol. • Hypertension and A:CR >30mg/mmol. • Any CKD with A:CR >70mg/mmol. Do not combine renin–angiotensinsin antagonists due to risk of hyperkalaemia and hypotension. Check K+ and renal function prior to, and 1–2 weeks after, starting treat- ment or changing dose. Stop if K+ >6mmol/L, eGFR >25%, or creatinine >30%: ex- clude other possible causes and consider a lower dose. Glycaemic control: Target HbA1C of ~53mmol/mol (7.0%) unless risk of hypo- glycaemia, comorbidity or limited life expectancy. Lifestyle: Off er advice about exercise, healthy weight, and smoking cessation. Salt intake should be reduced to <2g of sodium/day (=<5g sodium chloride/day). Treatment of renal complications of CKD Anaemia: Check Hb when eGFR <60. Investigate (especially if anaemic with eGFR >30) and treat other defi ciencies: iron (hypochromic red cells >6%, transferrin saturation <20%, ferritin <100), B12, and folate. Do not miss chronic blood loss. Iron therapy may need to be given IV. Consider treatment with an erythropoietic stimulating agent (ESA, ‘Epo’) if Hb <110g/L and likely to benefi t in terms of function and quality of life. Pure red cell aplasia is a very rare, severe complication of ESA treatment due to anti-erythropoietin antibodies and usually causes Hb <60g/L: exclude more common causes of anaemia fi rst. Acidosis: Consider sodium bicarbonate supplements for patients with eGFR <30 and low serum bicarbonate (<20mmol/L). Caution in patients with hypertension and fl uid overload due to sodium component. Oedema: Restrict fl uid and sodium intake. High doses of loop diuretics may be need- ed. Combination of a loop and thiazide diuretic can have a powerful eff ect: distal tubule sodium excretion (and its inhibition with a thiazide) is more signifi cant when already treated with a loop diuretic (fi g 7.13). Diuretic treatment should only be given with careful monitoring of fl uid state and renal function. CKD bone-mineral disorders: CKD causes in serum phosphate and reduced hy- droxlyation of vitamin D by the kidney. Measure calcium, phosphate, ALP, PTH, and 25-OH vit D if eGFR <30. • Treat if phosphate >1.5mmol/L (>1.7mmol/L if RRT) with dietary restriction ± phos- phate binders. The use of binders which do not contain calcium may be benefi cial in preventing vascular calcifi cation. • Give vitamin D supplements (colecalciferol, ergocalciferol) if defi cient. If PTH per- sists or is increasing, treat with an activated vit D analogue eg 1-calcidol or calci- triol. Paricalcitol suppresses PTH with less eff ect on gut absorption of calcium and phosphate and is less likely to cause calcium/phosphate. Restless legs/cramps: Exclude iron defi ciency as a possible exacerbating factor. Give sleep hygiene advice. Treatment for severe cases with gabapentin/pregabalin/ dopamine agonists is off licence and may be complicated by side-eff ects (falls, cogni- tive impairment, impulse-control disorder). Diet: Expert dietary advice should be available regarding protein intake, K+ if hyper- kalaemic, and phosphate restriction (eg dairy products). Treatment of other complications of CKD Cardiovascular disease: CKD confers risk of cardiovascular disease due to BP, vas- cular stiff ness, infl ammation, oxidative stress, and abnormal endothelial function (CV risk often higher than the risk of kidney failure). • Antiplatelets (low-dose aspirin) for CKD at risk for atherosclerotic events unless bleeding risk outweighs benefi t (mortality benefi t unclear in CKD). • Atorvastatin 20mg (and higher if GFR >30) for primary and secondary prevention of cardiovascular disease. • CKD should not aff ect treatment for heart failure but monitoring of GFR and K+ . • GFR <60 may aff ect troponin and BNP values. Interpret results cautiously with con- sideration for the GFR. Preparation for renal replacement therapy (RRT) Planning for RRT should begin in progressive CKD when the risk of renal failure is 10–20% within a year. Referral to nephrology less than 1 year before RRT is required is considered a late referral. All suitable patients should be listed for a deceased donor transplantation 6 months before the anticipated start of RRT. All suitable patients should be informed about the advantages of a pre-emptive living kidney transplant and eff orts made to fi nd a donor (p308). Prescribing in CKD Never prescribe in renal failure before checking how administration should be altered due to a GFR. This will be determined largely by the extent to which a drug is renally excreted. This is signifi cant for aminoglycosides, penicillins, cephalo sporins, heparin, lithium, opiates, and digoxin. Loading doses should not be changed. If precision is required for dosing (eg chemotherapy) then GFR should not be estimated from creatinine: a cystatin C or direct measure of GFR should be used. If the patient is receiving renal replacement (haemofi ltration, peritoneal or hae- modialysis), dose modifi cation depends on the extent to which a drug is cleared from the circulation by dialysis/fi ltration. The best prescribing guide to consult is the Renal Drug Database/Handbook (www.renaldrugdatabase.com), an invaluable resource detailing dose modifi cation in renal failure and in renal replacement for almost any drug you could wish to use. All hospitals should have access: speak to your pharmacist
| Intervention | Target / Detail |
|---|---|
| BP control | Systolic <140 mmHg (120-139); diastolic <90 mmHg. If DM or A:CR >70: systolic <130 mmHg, diastolic <80 mmHg |
| RAS blockade (ACE-i / ARB) | Offer if: DM + A:CR >3 mg/mmol; hypertension + A:CR >30 mg/mmol; any CKD + A:CR >70 mg/mmol. Do NOT combine. Check K⁺ and renal function before and 1-2 weeks after starting. Stop if K⁺ >6 mmol/L, eGFR drops >25%, or creatinine rises >30% |
| Glycaemic control | Target HbA1c ~53 mmol/mol (7.0%), adjusted for hypoglycaemia risk, comorbidity, or limited life expectancy |
| Lifestyle | Exercise, healthy weight, smoking cessation; sodium <2 g/day (<5 g NaCl/day) |
| Complication | Management |
|---|---|
| Anaemia | Check Hb when eGFR <60. Treat iron deficiency (hypochromic RBCs >6%, transferrin sat <20%, ferritin <100), B12, folate - IV iron if needed. ESA ('Epo') if Hb <110 g/L and likely to benefit. Rare: pure red cell aplasia from anti-EPO antibodies |
| Acidosis | Sodium bicarbonate if eGFR <30 and bicarbonate <20 mmol/L. Caution with hypertension/fluid overload |
| Oedema | Restrict fluid + sodium. High-dose loop diuretics ± thiazide combination (powerful synergistic effect on distal tubule Na⁺ excretion). Monitor fluid state and renal function closely |
| Bone-mineral disorders | Measure Ca²⁺, PO₄, ALP, PTH, 25-OH Vit D if eGFR <30. Treat phosphate >1.5 mmol/L with dietary restriction ± phosphate binders (non-calcium binders preferred to reduce vascular calcification). Vit D supplements if deficient; activated Vit D (alfacalcidol, calcitriol) if PTH persists; paricalcitol for PTH suppression with less effect on gut Ca/PO₄ absorption |
| Restless legs / cramps | Exclude iron deficiency. Sleep hygiene advice. Severe cases: gabapentin, pregabalin, or dopamine agonists (off-licence; risks: falls, cognitive impairment, impulse-control disorder) |
| Diet | Expert dietary advice on protein intake, potassium (if hyperkalaemic), and phosphate restriction (e.g. dairy products) |
Create a quick reference PDF for CKD management stages and thresholds
ls -la /tmp/workspace/ 2>/dev/null || mkdir -p /tmp/workspace && echo "created"
mkdir -p /tmp/workspace/ckd-pdf && python3 << 'EOF' from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import mm, cm from reportlab.platypus import ( SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, HRFlowable, KeepTogether ) from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT from reportlab.platypus import PageBreak # ── Colour palette ────────────────────────────────────────────────────────── NAVY = colors.HexColor('#1a3a5c') STEEL = colors.HexColor('#2e6da4') LIGHT_BLUE= colors.HexColor('#d6e8f7') MID_BLUE = colors.HexColor('#aaccee') TEAL = colors.HexColor('#1a7a6e') TEAL_LIGHT= colors.HexColor('#c8eae6') AMBER = colors.HexColor('#e67e22') AMBER_LIGHT= colors.HexColor('#fdebd0') RED = colors.HexColor('#c0392b') RED_LIGHT = colors.HexColor('#fadbd8') GREEN = colors.HexColor('#1e8449') GREEN_LIGHT= colors.HexColor('#d5f5e3') GREY_DARK = colors.HexColor('#4a4a4a') GREY_MID = colors.HexColor('#888888') GREY_LIGHT= colors.HexColor('#f0f4f8') WHITE = colors.white YELLOW_LIGHT = colors.HexColor('#fff9e6') # ── Document ───────────────────────────────────────────────────────────────── output_path = '/tmp/workspace/ckd-pdf/CKD_Quick_Reference.pdf' doc = SimpleDocTemplate( output_path, pagesize=A4, leftMargin=15*mm, rightMargin=15*mm, topMargin=18*mm, bottomMargin=18*mm ) W = A4[0] - 30*mm # usable width # ── Styles ─────────────────────────────────────────────────────────────────── styles = getSampleStyleSheet() def style(name, **kw): return ParagraphStyle(name, **kw) title_style = style('TitleS', fontName='Helvetica-Bold', fontSize=20, textColor=WHITE, alignment=TA_CENTER, spaceAfter=2) subtitle_style = style('SubtitleS', fontName='Helvetica', fontSize=10, textColor=LIGHT_BLUE, alignment=TA_CENTER, spaceAfter=0) section_style = style('SectionS', fontName='Helvetica-Bold', fontSize=11, textColor=WHITE, alignment=TA_LEFT, leftPadding=6, spaceAfter=4) body_style = style('BodyS', fontName='Helvetica', fontSize=8.5, textColor=GREY_DARK, leading=13) small_style = style('SmallS', fontName='Helvetica', fontSize=7.5, textColor=GREY_DARK, leading=11) bold_style = style('BoldS', fontName='Helvetica-Bold', fontSize=8.5, textColor=GREY_DARK) note_style = style('NoteS', fontName='Helvetica-Oblique', fontSize=7.5, textColor=GREY_MID, leading=11) cell_hdr = style('CellHdr', fontName='Helvetica-Bold', fontSize=8, textColor=WHITE, alignment=TA_CENTER) cell_body = style('CellBody', fontName='Helvetica', fontSize=8, textColor=GREY_DARK, alignment=TA_LEFT, leading=11) cell_center = style('CellCenter', fontName='Helvetica', fontSize=8, textColor=GREY_DARK, alignment=TA_CENTER, leading=11) cell_bold = style('CellBold', fontName='Helvetica-Bold', fontSize=8, textColor=GREY_DARK, alignment=TA_LEFT, leading=11) warn_style = style('WarnS', fontName='Helvetica-BoldOblique', fontSize=8, textColor=RED) story = [] # ════════════════════════════════════════════════════════════════════════════ # HEADER BANNER # ════════════════════════════════════════════════════════════════════════════ header_data = [[ Paragraph('CKD MANAGEMENT', title_style), Paragraph('Quick Reference Card', subtitle_style) ]] # Stack title + subtitle vertically header_data = [[Paragraph('CHRONIC KIDNEY DISEASE (CKD)', title_style)], [Paragraph('Management Quick Reference | Stages · Thresholds · Treatment Targets', subtitle_style)]] header_tbl = Table([[Paragraph('CHRONIC KIDNEY DISEASE (CKD)', title_style)], [Paragraph('Management Quick Reference | Stages · Thresholds · Treatment Targets', subtitle_style)]], colWidths=[W]) header_tbl.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,-1), NAVY), ('TOPPADDING', (0,0), (-1,-1), 10), ('BOTTOMPADDING', (0,0), (-1,-1), 6), ('LEFTPADDING', (0,0), (-1,-1), 8), ('RIGHTPADDING', (0,0), (-1,-1), 8), ('ROUNDEDCORNERS', [6]), ])) story.append(header_tbl) story.append(Spacer(1, 6)) # ════════════════════════════════════════════════════════════════════════════ # HELPER: section banner # ════════════════════════════════════════════════════════════════════════════ def section_banner(text, color=STEEL): t = Table([[Paragraph(text, section_style)]], colWidths=[W]) t.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,-1), color), ('TOPPADDING', (0,0), (-1,-1), 5), ('BOTTOMPADDING', (0,0), (-1,-1), 5), ('LEFTPADDING', (0,0), (-1,-1), 8), ('RIGHTPADDING', (0,0), (-1,-1), 8), ])) return t # ════════════════════════════════════════════════════════════════════════════ # 1. CKD STAGES (G categories) # ════════════════════════════════════════════════════════════════════════════ story.append(section_banner('1 CKD STAGES — G Categories (eGFR, mL/min/1.73 m²)', STEEL)) story.append(Spacer(1, 3)) stage_rows = [ [Paragraph('Stage', cell_hdr), Paragraph('eGFR Range', cell_hdr), Paragraph('Description', cell_hdr), Paragraph('Key Action', cell_hdr)], [Paragraph('G1', cell_bold), Paragraph('≥ 90', cell_center), Paragraph('Normal / high', cell_body), Paragraph('Monitor; treat underlying cause', cell_body)], [Paragraph('G2', cell_bold), Paragraph('60 – 89', cell_center), Paragraph('Mildly decreased', cell_body), Paragraph('Risk factor modification', cell_body)], [Paragraph('G3a', cell_bold), Paragraph('45 – 59', cell_center), Paragraph('Mildly to moderately decreased', cell_body), Paragraph('Cardio-renal risk management', cell_body)], [Paragraph('G3b', cell_bold), Paragraph('30 – 44', cell_center), Paragraph('Moderately to severely decreased', cell_body), Paragraph('Bone-mineral workup; anaemia screen', cell_body)], [Paragraph('G4', cell_bold), Paragraph('15 – 29', cell_center), Paragraph('Severely decreased', cell_body), Paragraph('Nephrology referral; RRT planning', cell_body)], [Paragraph('G5', cell_bold), Paragraph('< 15', cell_center), Paragraph('Kidney failure', cell_body), Paragraph('Urgent nephrology; initiate RRT', cell_body)], ] cw = [W*0.08, W*0.16, W*0.38, W*0.38] stage_tbl = Table(stage_rows, colWidths=cw, repeatRows=1) stage_tbl.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,0), NAVY), ('BACKGROUND', (0,1), (-1,1), WHITE), ('BACKGROUND', (0,2), (-1,2), GREY_LIGHT), ('BACKGROUND', (0,3), (-1,3), WHITE), ('BACKGROUND', (0,4), (-1,4), GREY_LIGHT), ('BACKGROUND', (0,5), (-1,5), AMBER_LIGHT), ('BACKGROUND', (0,6), (-1,6), RED_LIGHT), ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#cccccc')), ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('LEFTPADDING', (0,0), (-1,-1), 5), ('RIGHTPADDING', (0,0), (-1,-1), 5), ])) story.append(stage_tbl) story.append(Spacer(1, 5)) # ════════════════════════════════════════════════════════════════════════════ # 2. PROTEINURIA CATEGORIES # ════════════════════════════════════════════════════════════════════════════ story.append(section_banner('2 ALBUMINURIA / PROTEINURIA — A Categories (A:CR)', TEAL)) story.append(Spacer(1, 3)) acr_rows = [ [Paragraph('Category', cell_hdr), Paragraph('A:CR (mg/mmol)', cell_hdr), Paragraph('Description', cell_hdr), Paragraph('Significance', cell_hdr)], [Paragraph('A1', cell_bold), Paragraph('< 3', cell_center), Paragraph('Normal to mildly increased', cell_body), Paragraph('Baseline risk', cell_body)], [Paragraph('A2', cell_bold), Paragraph('3 – 30', cell_center), Paragraph('Moderately increased', cell_body), Paragraph('Offer ACE-i/ARB if DM + hypertension', cell_body)], [Paragraph('A3', cell_bold), Paragraph('> 30', cell_center), Paragraph('Severely increased', cell_body), Paragraph('RAS blockade if hypertension; refer if >70', cell_body)], ] acr_tbl = Table(acr_rows, colWidths=[W*0.10, W*0.20, W*0.35, W*0.35], repeatRows=1) acr_tbl.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,0), TEAL), ('BACKGROUND', (0,1), (-1,1), WHITE), ('BACKGROUND', (0,2), (-1,2), TEAL_LIGHT), ('BACKGROUND', (0,3), (-1,3), AMBER_LIGHT), ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#cccccc')), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('LEFTPADDING', (0,0), (-1,-1), 5), ('RIGHTPADDING', (0,0), (-1,-1), 5), ])) story.append(acr_tbl) story.append(Spacer(1, 5)) # ════════════════════════════════════════════════════════════════════════════ # 3. REFERRAL THRESHOLDS (two-column layout) # ════════════════════════════════════════════════════════════════════════════ story.append(section_banner('3 REFERRAL TO NEPHROLOGY — Thresholds', AMBER)) story.append(Spacer(1, 3)) ref_items = [ ('Stage', 'G4 or G5 CKD'), ('Proteinuria', 'A:CR > 70 mg/mmol (unless DM already treated)'), ('Proteinuria + haematuria', 'A:CR > 30 mg/mmol with haematuria'), ('Declining eGFR', 'Drop ≥25% AND change in GFR category'), ('Rapid decline', 'Sustained ≥15% fall within 12 months'), ('Resistant hypertension', 'BP poorly controlled on ≥4 drugs at therapeutic dose'), ('Aetiology', 'Known or suspected rare / genetic cause of CKD'), ] ref_rows = [[Paragraph('Indication', cell_hdr), Paragraph('Threshold / Criterion', cell_hdr)]] for item in ref_items: ref_rows.append([Paragraph(item[0], cell_bold), Paragraph(item[1], cell_body)]) ref_tbl = Table(ref_rows, colWidths=[W*0.30, W*0.70], repeatRows=1) ref_tbl.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,0), AMBER), ('BACKGROUND', (0,1), (-1,1), WHITE), ('BACKGROUND', (0,2), (-1,2), AMBER_LIGHT), ('BACKGROUND', (0,3), (-1,3), WHITE), ('BACKGROUND', (0,4), (-1,4), AMBER_LIGHT), ('BACKGROUND', (0,5), (-1,5), WHITE), ('BACKGROUND', (0,6), (-1,6), AMBER_LIGHT), ('BACKGROUND', (0,7), (-1,7), WHITE), ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#cccccc')), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('LEFTPADDING', (0,0), (-1,-1), 5), ('RIGHTPADDING', (0,0), (-1,-1), 5), ])) story.append(ref_tbl) story.append(Spacer(1, 5)) # ════════════════════════════════════════════════════════════════════════════ # 4. TREATMENT TARGETS (two-panel row) # ════════════════════════════════════════════════════════════════════════════ story.append(section_banner('4 TREATMENT TARGETS TO SLOW PROGRESSION', STEEL)) story.append(Spacer(1, 3)) targets = [ [Paragraph('Parameter', cell_hdr), Paragraph('Standard Target', cell_hdr), Paragraph('Target if DM / A:CR >70', cell_hdr)], [Paragraph('Systolic BP', cell_bold), Paragraph('< 140 mmHg (range 120–139)', cell_body), Paragraph('< 130 mmHg (range 120–129)', cell_body)], [Paragraph('Diastolic BP', cell_bold), Paragraph('< 90 mmHg', cell_body), Paragraph('< 80 mmHg', cell_body)], [Paragraph('HbA1c', cell_bold), Paragraph('~53 mmol/mol (7.0%)', cell_body), Paragraph('Adjust for hypoglycaemia risk / comorbidity', cell_body)], [Paragraph('Sodium intake', cell_bold), Paragraph('< 2 g Na/day (< 5 g NaCl/day)', cell_body), Paragraph('Same', cell_body)], ] tgt_tbl = Table(targets, colWidths=[W*0.22, W*0.38, W*0.40], repeatRows=1) tgt_tbl.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,0), NAVY), ('BACKGROUND', (0,1), (-1,1), WHITE), ('BACKGROUND', (0,2), (-1,2), LIGHT_BLUE), ('BACKGROUND', (0,3), (-1,3), WHITE), ('BACKGROUND', (0,4), (-1,4), LIGHT_BLUE), ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#cccccc')), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('LEFTPADDING', (0,0), (-1,-1), 5), ('RIGHTPADDING', (0,0), (-1,-1), 5), ])) story.append(tgt_tbl) story.append(Spacer(1, 3)) # RAS blockade box ras_text = ( '<b>RAS Blockade (ACE-i / ARB) Indications:</b> ' 'DM + A:CR >3 mg/mmol | Hypertension + A:CR >30 mg/mmol | Any CKD + A:CR >70 mg/mmol<br/>' '<font color="#c0392b"><b>Stop if:</b></font> ' 'K⁺ >6 mmol/L | eGFR drops >25% | Creatinine rises >30% — exclude other causes first. ' '<b>Never combine</b> ACE-i + ARB.' ) ras_tbl = Table([[Paragraph(ras_text, small_style)]], colWidths=[W]) ras_tbl.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,-1), YELLOW_LIGHT), ('BOX', (0,0), (-1,-1), 1, AMBER), ('TOPPADDING', (0,0), (-1,-1), 6), ('BOTTOMPADDING', (0,0), (-1,-1), 6), ('LEFTPADDING', (0,0), (-1,-1), 8), ('RIGHTPADDING', (0,0), (-1,-1), 8), ])) story.append(ras_tbl) story.append(Spacer(1, 5)) # ════════════════════════════════════════════════════════════════════════════ # 5. RENAL COMPLICATIONS (two-column side by side) # ════════════════════════════════════════════════════════════════════════════ story.append(section_banner('5 RENAL COMPLICATIONS — Triggers & Treatment', TEAL)) story.append(Spacer(1, 3)) comp_rows = [ [Paragraph('Complication', cell_hdr), Paragraph('Trigger / Threshold', cell_hdr), Paragraph('Management', cell_hdr)], [Paragraph('Anaemia', cell_bold), Paragraph('Check Hb if eGFR <60\nHb <110 g/L → ESA', cell_body), Paragraph('Iron (IV if needed), B12, folate. ESA if Hb <110 g/L + functional benefit', cell_body)], [Paragraph('Iron deficiency\n(triggers)', cell_bold), Paragraph('Hypochromic RBCs >6%\nTransferrin sat <20%\nFerritin <100 µg/L', cell_body), Paragraph('Oral or IV iron supplementation', cell_body)], [Paragraph('Acidosis', cell_bold), Paragraph('eGFR <30 + bicarb\n<20 mmol/L', cell_body), Paragraph('Sodium bicarbonate supplements\n⚠ Caution: hypertension / fluid overload', cell_body)], [Paragraph('Oedema', cell_bold), Paragraph('Fluid overload', cell_body), Paragraph('Fluid + Na restriction. High-dose loop diuretic ± thiazide (synergistic)', cell_body)], [Paragraph('Bone-mineral\ndisorders', cell_bold), Paragraph('Measure Ca/PO4/ALP/\nPTH/25-OH vit D if eGFR <30', cell_body), Paragraph('PO4 >1.5: diet ± non-Ca binders. Vit D if deficient. Activated Vit D (alfacalcidol/calcitriol) if PTH raised', cell_body)], [Paragraph('Restless legs\n/ cramps', cell_bold), Paragraph('Clinical; exclude\niron deficiency', cell_body), Paragraph('Sleep hygiene. Severe: gabapentin/pregabalin/dopamine agonists (off-licence)', cell_body)], ] comp_tbl = Table(comp_rows, colWidths=[W*0.18, W*0.28, W*0.54], repeatRows=1) comp_tbl.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,0), TEAL), ('BACKGROUND', (0,1), (-1,1), WHITE), ('BACKGROUND', (0,2), (-1,2), TEAL_LIGHT), ('BACKGROUND', (0,3), (-1,3), WHITE), ('BACKGROUND', (0,4), (-1,4), TEAL_LIGHT), ('BACKGROUND', (0,5), (-1,5), WHITE), ('BACKGROUND', (0,6), (-1,6), TEAL_LIGHT), ('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#cccccc')), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('LEFTPADDING', (0,0), (-1,-1), 5), ('RIGHTPADDING', (0,0), (-1,-1), 5), ])) story.append(comp_tbl) story.append(Spacer(1, 5)) # ════════════════════════════════════════════════════════════════════════════ # 6. CV RISK + RRT PREP (side by side boxes) # ════════════════════════════════════════════════════════════════════════════ story.append(section_banner('6 CARDIOVASCULAR RISK & RRT PREPARATION', colors.HexColor('#5b2c8d'))) story.append(Spacer(1, 3)) cv_text = ( '<b>Cardiovascular Management</b><br/>' '• Atorvastatin 20 mg — primary & secondary prevention<br/>' ' (higher dose if eGFR >30)<br/>' '• Low-dose aspirin — atherosclerotic event risk<br/>' ' (if bleeding risk acceptable)<br/>' '• HF treatment unaffected by CKD — monitor eGFR + K⁺<br/>' '• <b>Troponin / BNP:</b> interpret cautiously if eGFR <60' ) rrt_text = ( '<b>Renal Replacement Therapy (RRT)</b><br/>' '• Plan RRT when failure risk <b>10–20%</b> within 1 year<br/>' '• Referral <1 yr before RRT = <font color="#c0392b"><b>late referral</b></font><br/>' '• List for deceased donor transplant <b>6 months</b> before RRT<br/>' '• Discuss pre-emptive <b>living donor</b> transplant with all suitable patients' ) cv_tbl = Table([[Paragraph(cv_text, small_style)]], colWidths=[W*0.48]) cv_tbl.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,-1), colors.HexColor('#f0e8fa')), ('BOX', (0,0), (-1,-1), 1, colors.HexColor('#5b2c8d')), ('TOPPADDING', (0,0), (-1,-1), 7), ('BOTTOMPADDING', (0,0), (-1,-1), 7), ('LEFTPADDING', (0,0), (-1,-1), 7), ('RIGHTPADDING', (0,0), (-1,-1), 7), ])) rrt_tbl = Table([[Paragraph(rrt_text, small_style)]], colWidths=[W*0.48]) rrt_tbl.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,-1), colors.HexColor('#e8f0fa')), ('BOX', (0,0), (-1,-1), 1, STEEL), ('TOPPADDING', (0,0), (-1,-1), 7), ('BOTTOMPADDING', (0,0), (-1,-1), 7), ('LEFTPADDING', (0,0), (-1,-1), 7), ('RIGHTPADDING', (0,0), (-1,-1), 7), ])) dual_tbl = Table([[cv_tbl, Spacer(W*0.04, 1), rrt_tbl]], colWidths=[W*0.48, W*0.04, W*0.48]) dual_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), ])) story.append(dual_tbl) story.append(Spacer(1, 5)) # ════════════════════════════════════════════════════════════════════════════ # 7. PRESCRIBING CAUTION BOX # ════════════════════════════════════════════════════════════════════════════ rx_text = ( '<b>⚠ Prescribing in CKD</b><br/>' 'Always check dose adjustments before prescribing. ' 'Key drugs requiring modification: <b>aminoglycosides, penicillins, cephalosporins, heparin, lithium, opiates, digoxin.</b> ' 'Loading doses are NOT changed. ' 'For precision dosing (e.g. chemotherapy) use <b>cystatin C or direct GFR</b> — not creatinine estimate. ' 'For patients on dialysis/haemofiltration: dose depends on drug clearance by RRT modality. ' 'Consult: <b>Renal Drug Database</b> (www.renaldrugdatabase.com) or hospital pharmacist.' ) rx_tbl = Table([[Paragraph(rx_text, small_style)]], colWidths=[W]) rx_tbl.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,-1), RED_LIGHT), ('BOX', (0,0), (-1,-1), 1.5, RED), ('TOPPADDING', (0,0), (-1,-1), 7), ('BOTTOMPADDING', (0,0), (-1,-1), 7), ('LEFTPADDING', (0,0), (-1,-1), 10), ('RIGHTPADDING', (0,0), (-1,-1), 10), ])) story.append(rx_tbl) story.append(Spacer(1, 5)) # ════════════════════════════════════════════════════════════════════════════ # FOOTER # ════════════════════════════════════════════════════════════════════════════ footer_text = 'Source: Oxford Handbook of Clinical Medicine | For clinical use — verify against current local guidelines | Generated August 2026' footer_tbl = Table([[Paragraph(footer_text, note_style)]], colWidths=[W]) footer_tbl.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,-1), NAVY), ('TOPPADDING', (0,0), (-1,-1), 5), ('BOTTOMPADDING', (0,0), (-1,-1), 5), ('LEFTPADDING', (0,0), (-1,-1), 8), ('RIGHTPADDING', (0,0), (-1,-1), 8), ('FONTCOLOR', (0,0), (-1,-1), LIGHT_BLUE), ])) story.append(footer_tbl) # ── Build ──────────────────────────────────────────────────────────────────── doc.build(story) print(f"PDF created: {output_path}") EOF
ls -lh /tmp/workspace/ckd-pdf/CKD_Quick_Reference.pdf
| Section | Content |
|---|---|
| 1 - CKD G Stages | All 6 stages (G1-G5) with eGFR ranges, descriptions, and key actions - G4/G5 highlighted in amber/red |
| 2 - Albuminuria (A Categories) | A1/A2/A3 with A:CR thresholds and clinical significance |
| 3 - Referral Thresholds | All 7 nephrology referral indications with specific numeric criteria |
| 4 - Treatment Targets | BP, HbA1c, sodium targets - standard vs DM/high proteinuria columns + RAS blockade stop criteria box |
| 5 - Renal Complications | Anaemia, iron deficiency, acidosis, oedema, bone-mineral disorders, restless legs - with thresholds and management |
| 6 - CV Risk + RRT Prep | Statin/antiplatelet guidance + RRT planning milestones (10-20% risk trigger, 6-month listing rule) |
| 7 - Prescribing Caution | High-risk drugs, dose adjustment rules, cystatin C note, Renal Drug Database reference |
CKD Quick Reference
PDF Document · PDF