Create flash card on kidney function test

Reading File
Asking for Preferences
Finding Sources
Finding Sources
Reading File
Reading File
Finding Sources
Reading File
Reading File
Finding Sources
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Running Command

mkdir -p /home/daytona/workspace/kidney-flashcards && ls /home/daytona/workspace/kidney-flashcards/

Writing File

~/kidney-flashcards/generate_flashcards.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import PageBreak

OUTPUT = "/home/daytona/workspace/kidney-flashcards/Kidney_Function_Test_Flashcards.pdf"

# ── Colour palette ────────────────────────────────────────────────
DEEP_BLUE   = colors.HexColor("#1B3A6B")
MID_BLUE    = colors.HexColor("#2563EB")
LIGHT_BLUE  = colors.HexColor("#DBEAFE")
ACCENT      = colors.HexColor("#0F766E")   # teal for answer side
LIGHT_TEAL  = colors.HexColor("#CCFBF1")
WARN        = colors.HexColor("#DC2626")
WARN_LIGHT  = colors.HexColor("#FEE2E2")
GOLD        = colors.HexColor("#D97706")
GOLD_LIGHT  = colors.HexColor("#FEF9C3")
WHITE       = colors.white
GREY_TEXT   = colors.HexColor("#374151")

doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    leftMargin=1.5*cm, rightMargin=1.5*cm,
    topMargin=1.5*cm,  bottomMargin=1.5*cm,
)

styles = getSampleStyleSheet()

# Custom styles
def S(name, **kw):
    return ParagraphStyle(name, **kw)

title_style  = S("Title",  fontSize=22, fontName="Helvetica-Bold",
                 textColor=WHITE, alignment=TA_CENTER, spaceAfter=4)
sub_style    = S("Sub",    fontSize=11, fontName="Helvetica",
                 textColor=LIGHT_BLUE, alignment=TA_CENTER, spaceAfter=2)
q_label      = S("QLabel", fontSize=9,  fontName="Helvetica-Bold",
                 textColor=DEEP_BLUE,  spaceAfter=2)
q_text       = S("QText",  fontSize=13, fontName="Helvetica-Bold",
                 textColor=DEEP_BLUE,  alignment=TA_LEFT, leading=17, spaceAfter=4)
a_label      = S("ALabel", fontSize=9,  fontName="Helvetica-Bold",
                 textColor=ACCENT,     spaceAfter=2)
a_text       = S("AText",  fontSize=11, fontName="Helvetica",
                 textColor=GREY_TEXT,  alignment=TA_JUSTIFY, leading=16)
bullet_style = S("Bullet", fontSize=10, fontName="Helvetica",
                 textColor=GREY_TEXT,  leftIndent=12, leading=14,
                 bulletIndent=2)
note_style   = S("Note",   fontSize=9,  fontName="Helvetica-Oblique",
                 textColor=GOLD,       leading=13)
source_style = S("Source", fontSize=7.5, fontName="Helvetica-Oblique",
                 textColor=colors.HexColor("#6B7280"), alignment=TA_LEFT)

def cover_page():
    elems = []
    # Header block
    header_data = [[
        Paragraph("KIDNEY FUNCTION TESTS", title_style),
    ]]
    header_sub_data = [[
        Paragraph("Advanced Clinical Flashcards · Specialist Level", sub_style),
    ]]
    t1 = Table(header_data, colWidths=[18*cm])
    t1.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), DEEP_BLUE),
        ("TOPPADDING",    (0,0), (-1,-1), 20),
        ("BOTTOMPADDING", (0,0), (-1,-1), 6),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("RIGHTPADDING",  (0,0), (-1,-1), 10),
        ("ROUNDEDCORNERS", [10,10,0,0]),
    ]))
    t2 = Table(header_sub_data, colWidths=[18*cm])
    t2.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), MID_BLUE),
        ("TOPPADDING",    (0,0), (-1,-1), 6),
        ("BOTTOMPADDING", (0,0), (-1,-1), 16),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("RIGHTPADDING",  (0,0), (-1,-1), 10),
        ("ROUNDEDCORNERS", [0,0,10,10]),
    ]))
    elems += [t1, t2, Spacer(1, 0.6*cm)]

    info_text = [
        ("Total Cards", "25 Flashcards"),
        ("Topics",      "GFR · Creatinine · BUN · Cystatin C · Urine Markers · ACR · Novel Biomarkers · CKD Staging · Clinical Interpretation"),
        ("Level",       "Advanced — Clinical / Specialist"),
        ("Source",      "Henry's Laboratory Medicine · Comprehensive Clinical Nephrology · Brenner & Rector's The Kidney · Goldman-Cecil Medicine · Costanzo Physiology"),
    ]
    for label, val in info_text:
        row = [[
            Paragraph(f"<b>{label}:</b>  {val}", S("inf", fontSize=10, fontName="Helvetica",
                       textColor=GREY_TEXT, leading=14))
        ]]
        t = Table(row, colWidths=[18*cm])
        t.setStyle(TableStyle([
            ("BACKGROUND", (0,0), (-1,-1), LIGHT_BLUE),
            ("TOPPADDING",    (0,0), (-1,-1), 7),
            ("BOTTOMPADDING", (0,0), (-1,-1), 7),
            ("LEFTPADDING",   (0,0), (-1,-1), 14),
            ("RIGHTPADDING",  (0,0), (-1,-1), 14),
            ("BOX", (0,0), (-1,-1), 0.5, MID_BLUE),
        ]))
        elems += [t, Spacer(1, 0.25*cm)]

    elems.append(Spacer(1, 0.5*cm))
    elems.append(Paragraph(
        "Compiled from authoritative medical textbooks · May 2026",
        source_style))
    elems.append(PageBreak())
    return elems


def make_card(num, category, question, answer_bullets, note=None, source=None,
              warn=None, q_color=LIGHT_BLUE, q_border=MID_BLUE,
              a_color=LIGHT_TEAL, a_border=ACCENT):
    elems = []

    # ── QUESTION side ──────────────────────────────────────────────
    q_label_p  = Paragraph(f"CARD {num:02d}  ·  {category.upper()}", q_label)
    q_body     = Paragraph(question, q_text)

    q_block = Table([[q_label_p], [q_body]], colWidths=[17.5*cm])
    q_block.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), q_color),
        ("BOX",           (0,0), (-1,-1), 1.2, q_border),
        ("TOPPADDING",    (0,0), (-1,-1), 12),
        ("BOTTOMPADDING", (0,0), (-1,-1), 12),
        ("LEFTPADDING",   (0,0), (-1,-1), 16),
        ("RIGHTPADDING",  (0,0), (-1,-1), 16),
        ("ROUNDEDCORNERS", [8,8,8,8]),
    ]))
    elems.append(q_block)
    elems.append(Spacer(1, 0.3*cm))

    # ── ANSWER side ────────────────────────────────────────────────
    a_label_p = Paragraph("ANSWER", a_label)
    answer_rows = [[a_label_p]]
    for b in answer_bullets:
        answer_rows.append([Paragraph(b, bullet_style)])

    if warn:
        answer_rows.append([Spacer(1,4)])
        warn_p = Paragraph(f"⚠  {warn}", S("warn2", fontSize=9, fontName="Helvetica-Bold",
                             textColor=WARN, leading=13, leftIndent=6))
        answer_rows.append([warn_p])

    if note:
        answer_rows.append([Spacer(1,4)])
        answer_rows.append([Paragraph(note, note_style)])

    a_block = Table(answer_rows, colWidths=[17.5*cm])
    a_block.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), a_color),
        ("BOX",           (0,0), (-1,-1), 1.2, a_border),
        ("TOPPADDING",    (0,0), (-1,-1), 10),
        ("BOTTOMPADDING", (0,0), (-1,-1), 12),
        ("LEFTPADDING",   (0,0), (-1,-1), 16),
        ("RIGHTPADDING",  (0,0), (-1,-1), 16),
        ("ROUNDEDCORNERS", [8,8,8,8]),
    ]))
    elems.append(a_block)

    if source:
        elems.append(Spacer(1, 0.15*cm))
        elems.append(Paragraph(f"📚 {source}", source_style))

    elems.append(Spacer(1, 0.5*cm))
    return elems


# ─────────────────────────────────────────────────────────────────
# FLASHCARD DATA
# ─────────────────────────────────────────────────────────────────
cards = [
    # ── GFR ──────────────────────────────────────────────────────
    dict(
        num=1, category="GFR — Concept",
        question="What is the gold-standard marker for measuring GFR, and why is it ideal?",
        answer_bullets=[
            "• <b>Inulin</b> — the only perfect glomerular filtration marker.",
            "• Freely filtered, not bound to plasma proteins.",
            "• Not secreted, reabsorbed, synthesised, or metabolised by the kidney.",
            "• The urinary clearance of inulin is therefore exactly equal to GFR.",
            "• Limitation: it is exogenous and must be infused — impractical clinically.",
        ],
        note="Alternative exogenous markers: ¹²⁵I-iothalamate, ⁹⁹ᵐTc-DTPA, iohexol, ⁵¹Cr-EDTA.",
        source="Costanzo Physiology 7e; Henry's Laboratory Medicine",
    ),
    dict(
        num=2, category="GFR — Creatinine",
        question="Describe the physiology of creatinine as a GFR marker, including its production, handling, and key limitations.",
        answer_bullets=[
            "• <b>Production:</b> endogenous 113-Da molecule from muscle creatine/creatine-phosphate by nonenzymatic dehydration; proportional to muscle mass.",
            "• <b>Dietary source:</b> ingested meat (conversion increased by high temp, low pH).",
            "• <b>Renal handling:</b> freely filtered; NOT reabsorbed; small amount secreted (net effect ≈ filtered = excreted → slight overestimation of GFR).",
            "• <b>Formula:</b> GFR ≈ CrCl = U<sub>cr</sub> × V / P<sub>cr</sub>",
            "• <b>Limitations:</b> inter-individual variability with muscle mass; rises only when ~50% nephrons lost ('creatinine-blind' range); affected by tubular secretion inhibitors (TMP-SMX, cimetidine, cobicistat); falsely low in sarcopenia/vegetarian diet.",
        ],
        note="Creatinine production (men): 28 − 0.2×Age mg/kg/day; (women): 23.8 − 0.17×Age mg/kg/day.",
        source="Henry's Laboratory Medicine; Brenner & Rector's The Kidney",
        warn="In AKI with rapidly rising serum creatinine, eGFR equations are INVALID — use timed urine CrCl.",
    ),
    dict(
        num=3, category="GFR — Reference Ranges",
        question="What are the reference ranges for serum creatinine and BUN, and what is the normal GFR?",
        answer_bullets=[
            "• <b>Serum creatinine:</b> 0.5–1.0 mg/dL (some refs up to 1.5 mg/dL in muscular individuals).",
            "• <b>BUN (blood urea nitrogen):</b> 5–20 mg/dL (1.8–7.2 mmol urea/L).",
            "• <b>Normal GFR:</b> ≈ 90–120 mL/min/1.73 m² in healthy adults.",
            "• <b>CKD staging threshold:</b> GFR < 60 mL/min/1.73 m² for ≥ 3 months.",
            "• Filtration fraction = GFR / RPF ≈ 0.20 (20%).",
        ],
        source="Henry's Laboratory Medicine; Goldman-Cecil Medicine; Comprehensive Clinical Nephrology 7e",
    ),
    dict(
        num=4, category="GFR — eGFR Equations",
        question="Name the main eGFR estimation equations, their key variables, and clinically important caveats.",
        answer_bullets=[
            "• <b>Cockcroft-Gault:</b> [(140−Age) × Weight × 0.85♀] / (72 × Scr) → includes body weight; gives absolute mL/min.",
            "• <b>MDRD:</b> multi-variable; excludes weight; result in mL/min/1.73 m² — NOT applicable to obese, bedridden, amputees, or children.",
            "• <b>CKD-EPI (2021):</b> replaces race coefficient; uses age, sex, Scr — current KDOQI preferred equation for adults.",
            "• <b>Schwartz (paediatric):</b> 0.55 × height(cm) / Scr(mg/dL).",
            "• <b>Modified Schwartz (2009):</b> incorporates height, Scr, BUN, cystatin C.",
            "• All assume <i>stable</i> creatinine production — invalid in AKI.",
        ],
        note="K/DOQI guidelines recommend formula-based eGFR over direct 24-hr urine measurement due to collection errors.",
        source="Henry's Laboratory Medicine; Goldman-Cecil Medicine",
        warn="eGFR equations systematically overestimate GFR in sarcopenia/vegetarian diet and underestimate in large-muscle athletes.",
    ),
    # ── BUN ──────────────────────────────────────────────────────
    dict(
        num=5, category="BUN — Basics",
        question="What is BUN, how is it produced, and what factors — other than GFR — influence its level?",
        answer_bullets=[
            "• BUN = blood urea nitrogen; urea (H₂N-CO-NH₂) is the end product of NH₃ metabolism in the liver.",
            "• <b>BUN ∝ 1/GFR</b> — urea excretion is roughly proportional to GFR.",
            "• Unlike creatinine, urea undergoes tubular <i>reabsorption</i> (~50% of filtered load).",
            "• <b>Factors that RAISE BUN independently:</b> high protein intake, GI haemorrhage, catabolic states (sepsis, steroids), volume depletion (↑ proximal urea reabsorption).",
            "• <b>Factors that LOWER BUN independently:</b> malnutrition, liver failure, low-protein diet, pregnancy.",
        ],
        source="Henry's Laboratory Medicine; Costanzo Physiology 7e; Miller's Anesthesia 10e",
    ),
    dict(
        num=6, category="BUN/Creatinine Ratio",
        question="How do you interpret the BUN/Creatinine ratio clinically?",
        answer_bullets=[
            "• <b>Normal ratio:</b> 10:1 to 20:1",
            "• <b>Ratio > 20:1 (↑ BUN disproportionate to creatinine):</b>",
            "   — Prerenal azotemia (↓ perfusion → ↑ proximal urea reabsorption).",
            "   — GI haemorrhage (protein load).",
            "   — High catabolic state, high protein intake.",
            "   — Volume depletion.",
            "• <b>Ratio 10–20:1 (both rise proportionately):</b>",
            "   — Intrinsic renal disease (glomerulonephritis, ATN).",
            "   — Postrenal obstruction (obstructive uropathy).",
            "• <b>Ratio < 10:1 (↓ BUN relative to creatinine):</b>",
            "   — Liver failure, malnutrition, rhabdomyolysis.",
        ],
        note="Example: BUN 60 mg/dL + Cr 3.5 mg/dL → ratio ≈ 17 → true renal failure, not prerenal.",
        source="Henry's Laboratory Medicine; Costanzo Physiology 7e",
    ),
    # ── Cystatin C ────────────────────────────────────────────────
    dict(
        num=7, category="Cystatin C",
        question="What is cystatin C and why is it advantageous over creatinine as a GFR marker?",
        answer_bullets=[
            "• 13-kDa cysteine protease inhibitor produced at a constant rate by all nucleated cells.",
            "• Freely filtered at the glomerulus; completely reabsorbed and degraded by proximal tubule → normally undetectable in urine.",
            "• <b>Advantages:</b> NOT affected by muscle mass or dietary protein intake.",
            "• Shorter serum half-life than creatinine → detects GFR changes earlier in AKI.",
            "• Urinary cystatin C ↑ after tubular injury (impaired reabsorption) → marker of proximal tubular damage.",
        ],
        note="CKD-EPI cystatin C equation and combined Scr+Scys equation now recommended for confirmatory GFR estimation.",
        source="Brenner & Rector's The Kidney; Goldman-Cecil Medicine",
        warn="Cystatin C IS affected by: smoking, obesity, inflammation (CRP↑), thyroid dysfunction, glucocorticoids — independent of GFR.",
    ),
    # ── Proteinuria / ACR ─────────────────────────────────────────
    dict(
        num=8, category="Albuminuria / ACR",
        question="How is albuminuria measured and classified? What is its clinical significance in CKD?",
        answer_bullets=[
            "• Preferred method: <b>Albumin-to-Creatinine Ratio (ACR)</b> on random (ideally first morning) urine specimen.",
            "• ACR preferred over 24-hr urine collection — equally accurate, more convenient.",
            "• <b>KDIGO ACR Categories:</b>",
            "   A1: < 30 mg/g (Normal to mildly increased)",
            "   A2: 30–300 mg/g (Moderately increased)",
            "   A3: > 300 mg/g (Severely increased)",
            "• Albuminuria is more sensitive than total proteinuria in diabetic/hypertensive nephropathy.",
            "• High ACR independently predicts: CKD progression, cardiovascular mortality, all-cause mortality.",
        ],
        note="8-fold higher ACR associated with increased all-cause mortality across 21,688 CKD patients (13 studies).",
        source="Comprehensive Clinical Nephrology 7e; Brenner & Rector's The Kidney",
    ),
    dict(
        num=9, category="Proteinuria Classification",
        question="Classify proteinuria by mechanism and daily excretion thresholds.",
        answer_bullets=[
            "• <b>Glomerular proteinuria:</b> albumin dominant; reflects glomerular barrier damage.",
            "   — Nephrotic range: > 3.5 g/day (3500 mg/day).",
            "• <b>Tubular proteinuria:</b> low-MW proteins (β₂-microglobulin, RBP, α₁-microglobulin) due to impaired tubular reabsorption; albumin relatively spared.",
            "• <b>Overflow proteinuria:</b> Bence-Jones (light chains), myoglobin — exceeds tubular reabsorptive capacity.",
            "• <b>Functional/transient:</b> fever, exercise, orthostatic — resolves with the cause.",
            "• Urine PCR (protein-to-creatinine ratio) acceptable if ACR is high; ACR preferred for early detection.",
        ],
        source="Brenner & Rector's The Kidney; Comprehensive Clinical Nephrology 7e",
    ),
    # ── GFR Staging / CKD ─────────────────────────────────────────
    dict(
        num=10, category="CKD Staging",
        question="State the KDIGO GFR categories for CKD staging and describe the dual-axis risk classification.",
        answer_bullets=[
            "• <b>G1:</b> GFR ≥ 90 mL/min/1.73 m² (Normal or high; CKD if other kidney damage markers present)",
            "• <b>G2:</b> 60–89 (Mildly decreased)",
            "• <b>G3a:</b> 45–59 (Mildly-moderately decreased)",
            "• <b>G3b:</b> 30–44 (Moderately-severely decreased)",
            "• <b>G4:</b> 15–29 (Severely decreased)",
            "• <b>G5:</b> < 15 (Kidney failure)",
            "• Risk classification is <b>GFR category × Albuminuria category</b> (G1-5 × A1-3) → heat-map model.",
            "• CKD definition: structural/functional abnormality for ≥ 3 months.",
        ],
        note="KDIGO 2012 revision added albuminuria as a second axis to improve CV risk and progression prediction.",
        source="Comprehensive Clinical Nephrology 7e; Goldman-Cecil Medicine",
    ),
    # ── Novel Biomarkers ──────────────────────────────────────────
    dict(
        num=11, category="Novel AKI Biomarkers",
        question="List the key novel biomarkers of acute kidney injury (AKI) and describe their source and clinical timing.",
        answer_bullets=[
            "• <b>NGAL</b> (Neutrophil Gelatinase-Associated Lipocalin, 25 kDa): upregulated in tubular epithelium after ischemic/nephrotoxic injury; rises in urine/plasma within 2–6 hrs.",
            "• <b>KIM-1</b> (Kidney Injury Molecule-1): proximal tubule transmembrane protein shed into urine after injury; peak later than NGAL; less specific (also elevated in CKD, RCC).",
            "• <b>IL-18:</b> proinflammatory cytokine; urinary IL-18 rises within 6 hrs post-tubular injury.",
            "• <b>L-FABP</b> (Liver Fatty Acid-Binding Protein): expressed in proximal tubule; elevated within 6 hrs; sensitivity and specificity each ≈ 75%.",
            "• <b>TIMP-2 × IGFBP7:</b> best validated pair (AUC 0.80); approved for commercial use (NephroCheck™); outperforms NGAL, KIM-1, IL-18.",
        ],
        note="NGAL had AUC > 0.99 in paediatric cardiac surgery but failed to replicate across diverse settings.",
        source="Brenner & Rector's The Kidney",
    ),
    dict(
        num=12, category="Novel AKI Biomarkers",
        question="What is the FDA-approved bedside AKI test, and what biomarkers does it measure?",
        answer_bullets=[
            "• <b>NephroCheck™</b> — cleared by FDA for prediction of moderate–severe AKI (KDIGO stage 2–3) within 12 hrs.",
            "• Measures urinary <b>TIMP-2</b> (tissue inhibitor of metalloproteinase-2) and <b>IGFBP7</b> (insulin-like growth factor-binding protein 7).",
            "• These are G1 cell cycle arrest markers expressed by tubular epithelium under stress.",
            "• Result reported as [TIMP-2] × [IGFBP7]; threshold: >0.3 (pg/mL)²/1000 identifies high risk.",
            "• Identified from 340 candidate biomarkers in 522-patient discovery cohort + validated in 728 patients.",
        ],
        source="Brenner & Rector's The Kidney",
    ),
    # ── Urine Concentration ───────────────────────────────────────
    dict(
        num=13, category="Urine Osmolality & Concentration",
        question="How is urine osmolality used to localise the compartment of renal failure?",
        answer_bullets=[
            "• Kidney has two functional compartments: <b>filtration</b> (glomerulus) and <b>concentration</b> (tubules).",
            "• In a fluid-restricted patient, normal tubular function → U<sub>osm</sub>/P<sub>osm</sub> > 1.2.",
            "• <b>U<sub>osm</sub>/P<sub>osm</sub> < 1.2</b> (isosthenuria) → tubular dysfunction (loss of concentrating ability).",
            "• <b>Prerenal AKI:</b> intact tubules → urine maximally concentrated (U<sub>osm</sub> > 500 mOsm/kg).",
            "• <b>ATN (tubular injury):</b> isosthenuria (U<sub>osm</sub> ≈ 250–350 mOsm/kg ≈ plasma).",
            "• FE<sub>Na</sub> < 1% → prerenal; FE<sub>Na</sub> > 2% → intrinsic renal (ATN).",
        ],
        note="FEₙₐ = (U_Na × P_Cr) / (P_Na × U_Cr) × 100.",
        source="Henry's Laboratory Medicine",
    ),
    # ── Creatinine Clearance ──────────────────────────────────────
    dict(
        num=14, category="Creatinine Clearance",
        question="Explain the 24-hour creatinine clearance calculation and when it overestimates GFR.",
        answer_bullets=[
            "• <b>Formula:</b> CrCl (mL/min) = [U<sub>cr</sub> (mg/dL) × V (mL/24hr)] / [P<sub>cr</sub> (mg/dL) × 1440 min]",
            "• Overestimates true GFR because creatinine undergoes some tubular secretion.",
            "• At normal GFR, overestimation is modest; but as GFR declines, tubular secretion increases → overestimation worsens.",
            "• At renal clearance of 4 mL/min, extrarenal clearance (≈2 mL/min) can represent 1/3 of total plasma clearance.",
            "• 24-hr collection accuracy hinges on complete urine collection — a major practical limitation.",
        ],
        warn="In AKI with rapidly changing Scr, formula-based estimates are unreliable; timed 24-hr urine CrCl is preferred.",
        source="Henry's Laboratory Medicine",
    ),
    # ── Urea Clearance ───────────────────────────────────────────
    dict(
        num=15, category="Urea Clearance",
        question="Why is urea clearance a poor GFR estimator, and when does the BUN–creatinine ratio change?",
        answer_bullets=[
            "• ~50% of filtered urea is passively reabsorbed in the tubules → urea clearance underestimates GFR by ~50%.",
            "• In volume depletion: increased proximal reabsorption of all solutes (including urea) → BUN rises more than Scr → BUN/Cr ratio > 20.",
            "• In true renal failure: both BUN and creatinine rise proportionately → ratio remains 10–20.",
            "• Urea clearance is useful in tracking dialysis adequacy (Kt/V = dialysis dose).",
        ],
        source="Henry's Laboratory Medicine; Costanzo Physiology 7e",
    ),
    # ── Tubular Function ──────────────────────────────────────────
    dict(
        num=16, category="Tubular Function Tests",
        question="What tests assess tubular reabsorption, and what patterns indicate tubular injury?",
        answer_bullets=[
            "• <b>Urine osmolality:</b> maximal concentrating ability (> 900 mOsm/kg after water deprivation) — tests tubular concentrating function.",
            "• <b>FE<sub>Na</sub>:</b> < 1% = avid Na reabsorption (prerenal / normal tubules).",
            "• <b>Tubular proteinuria panel:</b> β₂-microglobulin, RBP (retinol-binding protein), α₁-microglobulin — ↑ in proximal tubule damage (Fanconi syndrome, aminoglycosides, contrast).",
            "• <b>Urinary cystatin C:</b> normally undetectable; rises with proximal tubular damage.",
            "• <b>NAG (N-acetyl-β-D-glucosaminidase):</b> lysosomal enzyme from proximal tubules; urinary NAG ↑ in tubular injury (sensitive early marker).",
            "• <b>Glucosuria without hyperglycaemia:</b> (Fanconi syndrome — SGLT2 failure).",
        ],
        source="Brenner & Rector's The Kidney; Tietz Textbook of Laboratory Medicine 7e",
    ),
    # ── Specific Tests ────────────────────────────────────────────
    dict(
        num=17, category="Drug Dosing & Kidney Function",
        question="How should kidney function be assessed for drug dosing decisions?",
        answer_bullets=[
            "• Use <b>eGFR or estimated CrCl</b> for drug dosing; FDA labelling often refers to CrCl (Cockcroft-Gault).",
            "• In very large or very small patients: adjust CrCl for body surface area (BSA = 1.73 m²).",
            "• Drugs renally dosed include: aminoglycosides, vancomycin, β-lactams, digoxin, LMWH, metformin, contrast agents.",
            "• Use actual body weight in Cockcroft-Gault; in obese patients use adjusted body weight.",
            "• Consider measuring true GFR (iohexol, iothalamate) when precision is critical (transplant dosing, chemotherapy).",
        ],
        note="Tietz Textbook recommends: if using eGFR in atypical body composition patients, always adjust for BSA.",
        source="Tietz Textbook of Laboratory Medicine 7e",
    ),
    dict(
        num=18, category="Renal Plasma Flow",
        question="How is renal plasma flow (RPF) measured, and what is its relationship to GFR?",
        answer_bullets=[
            "• RPF measured by <b>PAH clearance</b> (para-aminohippurate) — ~90% extracted in a single pass through the kidney.",
            "• C<sub>PAH</sub> ≈ ERPF (effective renal plasma flow).",
            "• <b>Filtration fraction (FF) = GFR / RPF ≈ 0.20</b> (20% of RPF filtered).",
            "• ↑ FF → ↑ protein concentration in peritubular capillaries → ↑ oncotic pressure → ↑ proximal tubule reabsorption.",
            "• In pregnancy: RPF ↑ 60–80% by mid-2nd trimester; GFR rises proportionately (Scr falls to ~0.8 mg/dL).",
        ],
        source="Creasy & Resnik's Maternal-Fetal Medicine; Costanzo Physiology 7e",
    ),
    dict(
        num=19, category="Pregnancy & Renal Tests",
        question="How do kidney function test values change in normal pregnancy?",
        answer_bullets=[
            "• GFR increases 40–60% by early 2nd trimester.",
            "• Serum creatinine falls to ~0.8 mg/dL (normal non-pregnant ≈ 0.9–1.0 mg/dL).",
            "• BUN also decreases proportionately.",
            "• Glycosuria common despite normoglycaemia (↑ GFR overwhelms tubular glucose reabsorption).",
            "• Mild proteinuria up to 300 mg/day may occur; ACR > 300 mg/g in pregnancy warrants investigation for preeclampsia.",
            "• A 'normal' creatinine of 1.0 mg/dL in pregnancy may represent significant renal impairment.",
        ],
        source="Creasy & Resnik's Maternal-Fetal Medicine; Campbell-Walsh-Wein Urology",
        warn="Standard upper limits of normal for Scr do NOT apply in pregnancy — use pregnancy-specific reference ranges.",
    ),
    dict(
        num=20, category="Isotope/Exogenous GFR Methods",
        question="What exogenous markers can directly measure GFR, and what are their comparative advantages?",
        answer_bullets=[
            "• <b>Inulin clearance (urinary):</b> gold standard — freely filtered, not secreted/reabsorbed. Requires inulin infusion + timed urine.",
            "• <b>¹²⁵I-Iothalamate / ⁹⁹ᵐTc-DTPA:</b> radioactive; accurate urinary clearance methods.",
            "• <b>Iohexol plasma clearance:</b> non-radioactive; no urine collection needed; less accurate than urinary methods.",
            "• <b>⁵¹Cr-EDTA:</b> used in Europe; plasma disappearance method.",
            "• Plasma clearance (without urine) is less accurate but more practical (avoids incomplete collection errors).",
        ],
        source="Henry's Laboratory Medicine",
    ),
    # ── Clinical Scenarios ────────────────────────────────────────
    dict(
        num=21, category="Clinical Scenario",
        question="A patient has BUN 80 mg/dL and Scr 4.0 mg/dL. The ratio is 20. Is this prerenal or intrinsic renal?",
        answer_bullets=[
            "• BUN/Cr ratio = 80/4 = 20 → borderline (at the upper limit of intrinsic).",
            "• Context is critical: assess volume status, urine Na, FE_Na, urine osmolality.",
            "• FE_Na < 1% + U_osm > 500 → <b>Prerenal</b>.",
            "• FE_Na > 2% + U_osm ≈ plasma → <b>ATN (intrinsic renal)</b>.",
            "• Clinical picture: dehydration, NSAID/ACEi use, cardiac failure → favour prerenal.",
            "• Pigmented granular casts in urine sediment → ATN.",
        ],
        note="Always interpret BUN/Cr ratio alongside clinical context and urine indices.",
        source="Henry's Laboratory Medicine; Rosen's Emergency Medicine",
        q_color=GOLD_LIGHT, q_border=GOLD,
    ),
    dict(
        num=22, category="Clinical Scenario",
        question="Why might a 75-year-old woman with Scr 0.9 mg/dL have significantly impaired renal function?",
        answer_bullets=[
            "• Scr is within the 'normal' lab reference range but this is MISLEADING in elderly women.",
            "• Elderly women have <b>reduced muscle mass</b> → less creatinine production → lower baseline Scr.",
            "• A Scr of 0.9 mg/dL in this patient may correspond to GFR of 40–50 mL/min (CKD G3a).",
            "• eGFR using CKD-EPI (incorporating age and sex) will correctly identify GFR reduction.",
            "• Drug dosing errors are common if creatinine alone is used without eGFR in elderly women.",
        ],
        warn="Never interpret Scr in isolation — always calculate eGFR, factoring in age, sex, and body composition.",
        source="Henry's Laboratory Medicine; Brenner & Rector's The Kidney",
        q_color=WARN_LIGHT, q_border=WARN,
    ),
    dict(
        num=23, category="Clinical Scenario",
        question="A patient post-cardiac surgery has rising urinary NGAL at 4 hours. Scr is still normal. What does this mean?",
        answer_bullets=[
            "• Rising urinary NGAL indicates <b>early tubular injury</b> — hours before Scr rises.",
            "• Scr lags because: (1) significant nephron loss must occur before Scr climbs; (2) volume of distribution dilutes Scr initially.",
            "• NGAL upregulation is triggered by ischemic/nephrotoxic tubular epithelial stress.",
            "• Clinical action: heightened vigilance, avoid nephrotoxins, optimise haemodynamics, consider nephrology consult.",
            "• Caveat: NGAL sensitivity/specificity vary across settings — strongest evidence in paediatric cardiac surgery (AUC > 0.99); lower in general ICU.",
        ],
        source="Brenner & Rector's The Kidney",
        q_color=GOLD_LIGHT, q_border=GOLD,
    ),
    dict(
        num=24, category="Urinalysis in Renal Assessment",
        question="What urinalysis findings help distinguish prerenal, intrinsic renal (ATN), and postrenal AKI?",
        answer_bullets=[
            "• <b>Prerenal:</b> high specific gravity (>1.020), U_osm > 500, few casts, FE_Na < 1%, U_Na < 10–20 mEq/L.",
            "• <b>ATN (intrinsic):</b> iso-osmolar urine (~280 mOsm), muddy-brown granular casts, renal tubular epithelial cells, FE_Na > 2%, U_Na > 40 mEq/L.",
            "• <b>Glomerulonephritis:</b> dysmorphic RBCs, RBC casts, proteinuria.",
            "• <b>Interstitial nephritis:</b> WBC casts, eosinophiluria (classic but not sensitive).",
            "• <b>Postrenal:</b> minimal casts; possible haematuria; obstruction confirmed by imaging (US).",
        ],
        source="Rosen's Emergency Medicine; Henry's Laboratory Medicine",
    ),
    dict(
        num=25, category="Summary — Test Overview",
        question="Summarise the key kidney function tests in a clinical framework.",
        answer_bullets=[
            "• <b>GFR estimation:</b> Scr + eGFR equation (CKD-EPI) → routine assessment; cystatin C for confirmation.",
            "• <b>Tubular damage:</b> Urinary cystatin C, NAG, β₂-microglobulin, NGAL, KIM-1.",
            "• <b>Glomerular integrity:</b> ACR, PCR, urine protein electrophoresis.",
            "• <b>Concentrating ability:</b> Urine osmolality, specific gravity.",
            "• <b>AKI prediction:</b> TIMP-2 × IGFBP7 (NephroCheck™).",
            "• <b>Perfusion:</b> FE_Na, BUN/Cr ratio, clinical assessment.",
            "• <b>Structural assessment:</b> Renal ultrasound, renal biopsy for definitive diagnosis.",
        ],
        note="CKD staging requires BOTH GFR (G1-G5) and Albuminuria (A1-A3) categories — dual-axis KDIGO classification.",
        source="Comprehensive Clinical Nephrology 7e; Goldman-Cecil Medicine; Brenner & Rector's The Kidney",
    ),
]

# ─────────────────────────────────────────────────────────────────
# BUILD DOCUMENT
# ─────────────────────────────────────────────────────────────────
story = cover_page()
for c in cards:
    story += make_card(**c)

doc.build(story)
print(f"PDF saved: {OUTPUT}")
You've run out of free credits. Sign up for a free account to continue using Orris.
This is a shared conversation. Sign in to Orris to start your own chat.