analyze and give suitable answers for 1st year mbbs student

Reading File
Running Command

cd /home/daytona/workspace/attachments/ea69af15-637b-4be7-adf1-5509f728b1a7/ && …

Reading File
All answers are written above. Here is a quick summary guide of all cases covered:

Quick Reference Summary

#Case LabelDiagnosisKey Clues
1MajorMyocardial InfarctionCK-MB 40%, ST elevation, chest pain
2MajorAcute PancreatitisAmylase/Lipase >3x, hypocalcemia, hyperglycemia, alcohol
3MajorMetabolic SyndromeObesity + HTN + hyperglycemia + acanthosis nigricans
4MajorVon Gierke's DiseaseHypoglycemia + hepatomegaly + hyperuricemia + lactic acidosis + G6Pase deficiency
5MajorStarvation KetoacidosisPregnant + vomiting + hypoglycemia + Rothera+, Benedict-
6MajorGoutUric acid 17.2, sodium urate crystals, after alcohol/purine meal
7MajorHemolytic JaundiceIndirect bili dominant, post-transfusion, dark stools, acholuric
8MajorObstructive Jaundice (Cholelithiasis)Direct bili dominant, ALP >>>, clay stools, absent urobilinogen
9MajorHepatic JaundiceBoth bili elevated, SGOT/SGPT very high, bile salts in urine
10MajorNephrotic SyndromeProteinuria >3.5g, hypoalbuminemia, hypercholesterolemia, edema
11MajorAcute GlomerulonephritisPost-streptococcal, hematuria, mild proteinuria, elevated urea/creatinine
12MajorHyperthyroidism (Graves')Exophthalmos, weight loss, tachycardia, goitre, elevated T3/T4, low TSH
13MajorEuthyroidAll TFTs normal
14MajorProstate CarcinomaPSA 42, hard nodular prostate, elderly male
15MajorBreast CarcinomaFirm immobile mass, nipple retraction, postmenopausal
16MajorDKAHyperglycemia + acidosis + Rothera+ + Benedict+, no insulin
17MajorRespiratory AcidosisAsthmatic, pH low, pCO2 high, HCO3 compensatorily high
18MajorRespiratory AlkalosisAnxiety, hyperventilation, pH high, pCO2 low, ionized Ca low
19MajorNAFLDObese, T2DM, no alcohol, ALT>AST, Grade II fatty liver
20MajorPhenylketonuriaHigh phenylalanine, urine keto acids, mental retardation, pale skin
21/22MajorKwashiorkorProtein deficiency, edema, fatty liver, hair/skin changes, weaned child
23MajorStarvation KetoacidosisSame as Case 5
M1MinorGalactosemiaGALT deficiency, cataract, mucic acid+, Benedict+, glucose-
M2MinorAlkaptonuriaHomogentisate oxidase deficiency, darkening urine, ferric chloride+
M3MinorHomocystinuriaCBS deficiency, ectopia lentis, marfanoid, nitroprusside+, B6 non-responsive
M4MinorMSUDBCKDH deficiency, maple syrup urine, elevated LIV amino acids
M5MinorAlbinismTyrosinase deficiency, no melanin, pale skin/hair/eyes, AR
M6/7MinorVitamin A DeficiencyNight blindness, Bitot's spots, low retinol, low RBP
M8MinorRicketsLow calcitriol, high ALP, low Ca/PO4, bone deformities
M9/10MinorScurvyVitamin C deficiency, bleeding gums, petechiae, defective collagen
M11MinorBeriberi (Wet)Thiamine deficiency, polished rice, edema, cardiac failure
M12-14MinorPellagraNiacin deficiency, corn diet, 4 D's: Dermatitis, Diarrhea, Dementia, Death
M15MinorMegaloblastic AnemiaB12 + Folate deficiency, high MCV, hypersegmented neutrophils
M16MinorIron Deficiency AnemiaLow ferritin + low serum iron, microcytic, pica, brittle nails
M17MinorTetanyPost-thyroidectomy, hypoparathyroidism, hypocalcemia, carpopedal spasms
M18MinorGoitreIodine deficiency/Hashimoto's, diffuse neck swelling, hypothyroid symptoms
M19MinorFluorosisExcess fluoride, mottled teeth, skeletal stiffness, high serum F
M20MinorCystinuriaRenal COLA transporter defect, hexagonal crystals, nitroprusside+, kidney stones
All answers are written at 1st year MBBS biochemistry level, aligned with Harper's, Lehninger, and standard Indian medical curriculum. For the 2 cases that contained images (Obstructive Jaundice table and Thyroid function table), the answers are based on the expected typical lab pattern as described in the document labels.

Create a study summary PDF with flow charts for case diagnosis

Reading File
Running Command

mkdir -p /home/daytona/workspace/mbbs-study-pdf && ls /home/daytona/workspace/mb…

Writing File

~/mbbs-study-pdf/generate_pdf.py

#!/usr/bin/env python3
"""
MBBS 1st Year Biochemistry Case Study Summary PDF
with Diagnosis Flowcharts
"""

from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.colors import (
    HexColor, white, black, Color
)
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    PageBreak, HRFlowable, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.graphics.shapes import (
    Drawing, Rect, String, Line, Polygon, Arrow,
    Group, Circle
)
from reportlab.graphics import renderPDF
import textwrap

# ─── COLOUR PALETTE ──────────────────────────────────────────────────────────
C_NAVY      = HexColor('#1a2a4a')
C_BLUE      = HexColor('#2563EB')
C_LIGHT_BLU = HexColor('#DBEAFE')
C_TEAL      = HexColor('#0F766E')
C_TEAL_LT   = HexColor('#CCFBF1')
C_RED       = HexColor('#DC2626')
C_RED_LT    = HexColor('#FEE2E2')
C_GREEN     = HexColor('#16A34A')
C_GREEN_LT  = HexColor('#DCFCE7')
C_ORANGE    = HexColor('#D97706')
C_ORANGE_LT = HexColor('#FEF3C7')
C_PURPLE    = HexColor('#7C3AED')
C_PURPLE_LT = HexColor('#EDE9FE')
C_GRAY      = HexColor('#6B7280')
C_GRAY_LT   = HexColor('#F3F4F6')
C_DARK      = HexColor('#111827')
C_WHITE     = white

PAGE_W, PAGE_H = A4

# ─── STYLES ──────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

def make_style(name, **kw):
    base = kw.pop('parent', 'Normal')
    s = ParagraphStyle(name, parent=styles[base], **kw)
    styles.add(s)
    return s

TITLE_STYLE = make_style('MyTitle',
    fontSize=26, leading=32, textColor=C_WHITE,
    fontName='Helvetica-Bold', alignment=TA_CENTER, spaceAfter=6)

SUBTITLE_STYLE = make_style('MySubtitle',
    fontSize=13, leading=18, textColor=HexColor('#BFDBFE'),
    fontName='Helvetica', alignment=TA_CENTER, spaceAfter=4)

H1 = make_style('MyH1',
    fontSize=16, leading=20, textColor=C_WHITE,
    fontName='Helvetica-Bold', alignment=TA_LEFT,
    spaceBefore=2, spaceAfter=2)

H2 = make_style('MyH2',
    fontSize=12, leading=16, textColor=C_NAVY,
    fontName='Helvetica-Bold', alignment=TA_LEFT,
    spaceBefore=6, spaceAfter=3)

H3 = make_style('MyH3',
    fontSize=10, leading=14, textColor=C_TEAL,
    fontName='Helvetica-Bold', alignment=TA_LEFT,
    spaceBefore=4, spaceAfter=2)

BODY = make_style('MyBody',
    fontSize=9, leading=13, textColor=C_DARK,
    fontName='Helvetica', alignment=TA_LEFT,
    spaceBefore=2, spaceAfter=2)

BODY_BOLD = make_style('MyBodyBold',
    fontSize=9, leading=13, textColor=C_DARK,
    fontName='Helvetica-Bold', alignment=TA_LEFT)

SMALL = make_style('MySmall',
    fontSize=8, leading=11, textColor=C_GRAY,
    fontName='Helvetica', alignment=TA_LEFT)

BULLET = make_style('MyBullet',
    fontSize=9, leading=13, textColor=C_DARK,
    fontName='Helvetica', leftIndent=14, bulletIndent=4,
    bulletFontName='Helvetica', spaceAfter=1)

CENTER = make_style('MyCenter',
    fontSize=9, leading=13, textColor=C_DARK,
    fontName='Helvetica', alignment=TA_CENTER)

DIAG_LABEL = make_style('MyDiag',
    fontSize=10, leading=13, textColor=C_WHITE,
    fontName='Helvetica-Bold', alignment=TA_CENTER)

# ─── FLOWCHART HELPER ────────────────────────────────────────────────────────

class FlowChart(Flowable):
    """
    Draws a linear diagnostic flowchart:
    steps = list of dicts:
        type: 'box' | 'diamond' | 'oval'
        text: string
        color: HexColor (fill)
        tcolor: HexColor (text)
    arrows between each step.
    Fits into given width; height computed automatically.
    """
    BOX_H    = 34
    DIAM_H   = 38
    OVAL_H   = 32
    ARROW_H  = 18
    PAD_X    = 10
    PAD_Y    = 6

    def __init__(self, steps, width=None, font_size=8):
        super().__init__()
        self.steps = steps
        self._w = width or (PAGE_W - 4*cm)
        self.font_size = font_size
        # compute height
        h = 6
        for s in steps:
            t = s.get('type', 'box')
            if t == 'diamond': h += self.DIAM_H
            elif t == 'oval':  h += self.OVAL_H
            else:              h += self.BOX_H
            h += self.ARROW_H
        h -= self.ARROW_H
        h += 6
        self.height = h
        self.width  = self._w

    def wrap(self, availW, availH):
        return (self.width, self.height)

    def draw(self):
        c = self.canv
        x0 = 0
        cx = self._w / 2
        y  = self.height - 6
        box_w = self._w * 0.72
        bx = cx - box_w/2

        for i, step in enumerate(self.steps):
            t      = step.get('type', 'box')
            text   = step.get('text', '')
            fill   = step.get('color', C_BLUE)
            tcolor = step.get('tcolor', C_WHITE)

            if t == 'oval':
                sh = self.OVAL_H
            elif t == 'diamond':
                sh = self.DIAM_H
            else:
                sh = self.BOX_H

            top  = y
            bot  = y - sh
            midY = (top + bot) / 2

            if t == 'box':
                c.setFillColor(fill)
                c.setStrokeColor(C_NAVY)
                c.setLineWidth(0.8)
                c.roundRect(bx, bot, box_w, sh, 5, fill=1, stroke=1)

            elif t == 'oval':
                c.setFillColor(fill)
                c.setStrokeColor(C_NAVY)
                c.setLineWidth(0.8)
                c.ellipse(bx, bot, bx+box_w, top, fill=1, stroke=1)

            elif t == 'diamond':
                mx = cx
                pts = [mx, top,  bx+box_w, midY,  mx, bot,  bx, midY]
                p = c.beginPath()
                p.moveTo(pts[0], pts[1])
                p.lineTo(pts[2], pts[3])
                p.lineTo(pts[4], pts[5])
                p.lineTo(pts[6], pts[7])
                p.close()
                c.setFillColor(fill)
                c.setStrokeColor(C_NAVY)
                c.setLineWidth(0.8)
                c.drawPath(p, fill=1, stroke=1)

            # text
            c.setFillColor(tcolor)
            c.setFont('Helvetica-Bold', self.font_size)
            lines = self._wrap_text(text, box_w - 2*self.PAD_X, self.font_size)
            total_th = len(lines) * (self.font_size + 2)
            ty = midY + total_th/2 - self.font_size
            for ln in lines:
                c.drawCentredString(cx, ty, ln)
                ty -= (self.font_size + 2)

            y = bot

            # arrow
            if i < len(self.steps) - 1:
                ay_top = y
                ay_bot = y - self.ARROW_H
                c.setStrokeColor(C_GRAY)
                c.setFillColor(C_GRAY)
                c.setLineWidth(1.2)
                c.line(cx, ay_top, cx, ay_bot + 5)
                # arrowhead
                aw = 5
                p2 = c.beginPath()
                p2.moveTo(cx, ay_bot)
                p2.lineTo(cx - aw, ay_bot + 7)
                p2.lineTo(cx + aw, ay_bot + 7)
                p2.close()
                c.drawPath(p2, fill=1, stroke=0)
                y = ay_bot

    def _wrap_text(self, text, max_w, fsize):
        # estimate chars per line
        char_w = fsize * 0.52
        cpl = max(1, int(max_w / char_w))
        return textwrap.wrap(text, width=cpl) or [text]


class SideBySideFlowChart(Flowable):
    """Two-column flowchart for comparison."""
    STEP_H = 28
    GAP_H  = 16
    PAD    = 6

    def __init__(self, left_steps, right_steps, left_title, right_title,
                 width=None, font_size=8):
        super().__init__()
        self._w = width or (PAGE_W - 4*cm)
        self.font_size = font_size
        self.left_steps  = left_steps
        self.right_steps = right_steps
        self.left_title  = left_title
        self.right_title = right_title
        n = max(len(left_steps), len(right_steps))
        self.height = 28 + n*(self.STEP_H + self.GAP_H) + 10
        self.width  = self._w

    def wrap(self, aw, ah):
        return (self.width, self.height)

    def draw(self):
        c    = self.canv
        col_w = (self._w - 10) / 2
        lx   = 0
        rx   = col_w + 10

        # headers
        for x, title, color in [(lx, self.left_title, C_BLUE),
                                 (rx, self.right_title, C_TEAL)]:
            c.setFillColor(color)
            c.setStrokeColor(color)
            c.roundRect(x, self.height-24, col_w, 20, 4, fill=1, stroke=0)
            c.setFillColor(C_WHITE)
            c.setFont('Helvetica-Bold', 9)
            c.drawCentredString(x + col_w/2, self.height-17, title)

        y = self.height - 30
        for i in range(max(len(self.left_steps), len(self.right_steps))):
            for steps, x, color in [(self.left_steps,  lx, C_BLUE),
                                     (self.right_steps, rx, C_TEAL)]:
                if i < len(steps):
                    s = steps[i]
                    fill = s.get('color', color)
                    text = s.get('text', '')
                    c.setFillColor(fill)
                    c.setStrokeColor(HexColor('#94A3B8'))
                    c.setLineWidth(0.5)
                    c.roundRect(x, y-self.STEP_H, col_w, self.STEP_H, 4, fill=1, stroke=1)
                    c.setFillColor(s.get('tcolor', C_WHITE))
                    c.setFont('Helvetica-Bold', self.font_size)
                    lines = textwrap.wrap(text, width=int(col_w*0.17))
                    total_th = len(lines)*(self.font_size+2)
                    ty = (y - self.STEP_H/2) + total_th/2 - self.font_size
                    for ln in lines:
                        c.drawCentredString(x + col_w/2, ty, ln)
                        ty -= (self.font_size+2)
                    # downward arrow
                    if i < max(len(self.left_steps), len(self.right_steps))-1 and i < len(steps)-1:
                        ax = x + col_w/2
                        ay_t = y - self.STEP_H
                        ay_b = ay_t - self.GAP_H + 4
                        c.setStrokeColor(C_GRAY)
                        c.setFillColor(C_GRAY)
                        c.setLineWidth(1)
                        c.line(ax, ay_t, ax, ay_b+4)
                        aw2 = 4
                        p = c.beginPath()
                        p.moveTo(ax, ay_b)
                        p.lineTo(ax-aw2, ay_b+6)
                        p.lineTo(ax+aw2, ay_b+6)
                        p.close()
                        c.drawPath(p, fill=1, stroke=0)
            y -= (self.STEP_H + self.GAP_H)


# ─── SECTION HEADER FLOWABLE ─────────────────────────────────────────────────

class SectionHeader(Flowable):
    def __init__(self, title, subtitle='', color=C_NAVY, width=None):
        super().__init__()
        self.title    = title
        self.subtitle = subtitle
        self.color    = color
        self._w       = width or (PAGE_W - 4*cm)
        self.height   = 46 if subtitle else 36

    def wrap(self, aw, ah):
        return (self._w, self.height)

    def draw(self):
        c = self.canv
        c.setFillColor(self.color)
        c.roundRect(0, 0, self._w, self.height, 6, fill=1, stroke=0)
        c.setFillColor(C_WHITE)
        c.setFont('Helvetica-Bold', 13)
        ty = self.height - 18 if self.subtitle else (self.height-13)/2
        c.drawString(12, ty, self.title)
        if self.subtitle:
            c.setFont('Helvetica', 8)
            c.setFillColor(HexColor('#CBD5E1'))
            c.drawString(12, 8, self.subtitle)


# ─── KEY BOX FLOWABLE ────────────────────────────────────────────────────────

def key_box(label, value, bg=C_LIGHT_BLU, fg=C_NAVY):
    data = [[Paragraph(f'<b>{label}</b>', BODY_BOLD),
             Paragraph(value, BODY)]]
    t = Table(data, colWidths=['30%', '70%'])
    t.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (0,-1), bg),
        ('BACKGROUND', (1,0), (1,-1), C_WHITE),
        ('TEXTCOLOR',  (0,0), (-1,-1), fg),
        ('BOX',        (0,0), (-1,-1), 0.5, C_GRAY),
        ('INNERGRID',  (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 6),
        ('RIGHTPADDING', (0,0), (-1,-1), 6),
        ('VALIGN',     (0,0), (-1,-1), 'MIDDLE'),
        ('ROUNDEDCORNERS', [4]),
    ]))
    return t


def info_table(rows, col_ratio=None, header_color=C_NAVY):
    col_ratio = col_ratio or [35, 65]
    cw = [(PAGE_W - 4*cm) * r/100 for r in col_ratio]
    data = []
    for i, row in enumerate(rows):
        data.append([Paragraph(str(row[0]), BODY_BOLD if i==0 else BODY),
                     Paragraph(str(row[1]), BODY)])
    t = Table(data, colWidths=cw)
    ts = [
        ('BACKGROUND', (0,0), (-1,0), header_color),
        ('TEXTCOLOR',  (0,0), (-1,0), C_WHITE),
        ('FONTNAME',   (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE',   (0,0), (-1,-1), 9),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
        ('BOX',        (0,0), (-1,-1), 0.5, C_GRAY),
        ('INNERGRID',  (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 6),
        ('RIGHTPADDING', (0,0), (-1,-1), 6),
        ('VALIGN',     (0,0), (-1,-1), 'MIDDLE'),
    ]
    t.setStyle(TableStyle(ts))
    return t


def colored_box_para(text, bg=C_LIGHT_BLU, fg=C_NAVY, font_size=9):
    data = [[Paragraph(text, ParagraphStyle('_tmp', fontSize=font_size,
                                             fontName='Helvetica', textColor=fg,
                                             leading=font_size+3))]]
    t = Table(data, colWidths=[PAGE_W - 4*cm])
    t.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,-1), bg),
        ('BOX',        (0,0), (-1,-1), 0.5, fg),
        ('TOPPADDING', (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
        ('LEFTPADDING', (0,0), (-1,-1), 8),
        ('RIGHTPADDING', (0,0), (-1,-1), 8),
        ('ROUNDEDCORNERS', [4]),
    ]))
    return t


# ─── COVER PAGE ──────────────────────────────────────────────────────────────

def cover_page(story):
    # gradient-like cover using a drawing
    d = Drawing(PAGE_W - 4*cm, 160)
    d.add(Rect(0, 0, PAGE_W-4*cm, 160,
               fillColor=C_NAVY, strokeColor=None))
    d.add(Rect(0, 120, PAGE_W-4*cm, 40,
               fillColor=C_BLUE, strokeColor=None))
    d.add(Rect(0, 0, 8, 160,
               fillColor=C_TEAL, strokeColor=None))
    story.append(Spacer(1, 0.3*cm))
    story.append(d)

    # overlay text as paragraphs AFTER the drawing
    title_data = [[Paragraph(
        '<font color="#FFFFFF"><b>1st Year MBBS Biochemistry</b></font>',
        ParagraphStyle('ct', fontSize=20, fontName='Helvetica-Bold',
                       alignment=TA_CENTER, leading=26,
                       textColor=C_WHITE))]]
    tt = Table(title_data, colWidths=[PAGE_W-4*cm])
    tt.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,-1), C_NAVY),
        ('TOPPADDING', (0,0), (-1,-1), 6),
        ('BOTTOMPADDING', (0,0), (-1,-1), 2),
    ]))
    story.append(tt)

    sub_data = [[Paragraph(
        '<font color="#93C5FD"><b>Case Study Summary with Diagnosis Flowcharts</b></font>',
        ParagraphStyle('cs', fontSize=12, fontName='Helvetica',
                       alignment=TA_CENTER, leading=16, textColor=HexColor('#93C5FD')))]]
    st = Table(sub_data, colWidths=[PAGE_W-4*cm])
    st.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,-1), C_NAVY),
        ('TOPPADDING', (0,0), (-1,-1), 2),
        ('BOTTOMPADDING', (0,0), (-1,-1), 8),
    ]))
    story.append(st)

    # accent bar
    story.append(HRFlowable(width='100%', thickness=3, color=C_TEAL))
    story.append(Spacer(1, 0.4*cm))

    # Quick guide table
    story.append(Paragraph('📋  Cases Covered in This Summary', H2))
    story.append(Spacer(1, 0.2*cm))

    toc_data = [
        ['#', 'Case / Diagnosis', 'System', 'Page'],
        ['1',  'Myocardial Infarction',            'Cardiology',         '2'],
        ['2',  'Acute Pancreatitis',               'GI / Pancreas',      '3'],
        ['3',  'Metabolic Syndrome',               'Metabolism',         '4'],
        ['4',  "Von Gierke's Disease",             'Glycogen Metabolism','5'],
        ['5',  'Starvation Ketoacidosis',          'Metabolism',         '6'],
        ['6',  'Gout',                             'Purine Metabolism',  '7'],
        ['7',  'Hemolytic Jaundice',               'Hepatology',         '8'],
        ['8',  'Obstructive Jaundice',             'Hepatology',         '9'],
        ['9',  'Hepatic Jaundice',                 'Hepatology',        '10'],
        ['10', 'Nephrotic Syndrome',               'Nephrology',        '11'],
        ['11', 'Acute Glomerulonephritis',         'Nephrology',        '12'],
        ['12', 'Hyperthyroidism',                  'Endocrinology',     '13'],
        ['13', 'DKA & Metabolic Acidosis',         'Metabolism',        '14'],
        ['14', 'Respiratory Acidosis/Alkalosis',   'Acid-Base',         '15'],
        ['15', 'NAFLD',                            'Hepatology',        '16'],
        ['16', 'Phenylketonuria',                  'Amino Acid Metab',  '17'],
        ['17', 'Kwashiorkor',                      'Nutrition',         '18'],
        ['M1', 'Galactosemia',                     'Carb Metabolism',   '19'],
        ['M2', 'Alkaptonuria',                     'Amino Acid Metab',  '19'],
        ['M3', 'Homocystinuria / MSUD',            'Amino Acid Metab',  '20'],
        ['M4', 'Albinism',                         'Amino Acid Metab',  '20'],
        ['M5', 'Vitamin Deficiencies',             'Nutrition',         '21'],
        ['M6', 'Anemias (IDA, Megaloblastic)',     'Hematology',        '22'],
        ['M7', 'Tetany / Goitre / Fluorosis',      'Minerals',          '22'],
        ['M8', 'Cystinuria',                       'Amino Acid Metab',  '23'],
    ]
    cw = [1.0*cm, 7.5*cm, 4.5*cm, 1.5*cm]
    toc_t = Table(toc_data, colWidths=cw)
    toc_t.setStyle(TableStyle([
        ('BACKGROUND',    (0,0),  (-1,0),  C_NAVY),
        ('TEXTCOLOR',     (0,0),  (-1,0),  C_WHITE),
        ('FONTNAME',      (0,0),  (-1,0),  'Helvetica-Bold'),
        ('FONTSIZE',      (0,0),  (-1,-1), 8),
        ('ROWBACKGROUNDS',(0,1),  (-1,-1), [C_WHITE, C_GRAY_LT]),
        ('BOX',           (0,0),  (-1,-1), 0.5, C_GRAY),
        ('INNERGRID',     (0,0),  (-1,-1), 0.2, HexColor('#E5E7EB')),
        ('TOPPADDING',    (0,0),  (-1,-1), 3),
        ('BOTTOMPADDING', (0,0),  (-1,-1), 3),
        ('LEFTPADDING',   (0,0),  (-1,-1), 5),
        ('ALIGN',         (0,0),  (0,-1),  'CENTER'),
        ('ALIGN',         (3,0),  (3,-1),  'CENTER'),
    ]))
    story.append(toc_t)
    story.append(PageBreak())


# ─── CASE BUILDERS ───────────────────────────────────────────────────────────

def add_case(story, number, title, system, color, flowchart_steps,
             labs_rows, key_points, mnemonics=None, note=None):
    """Generic case adder."""
    story.append(SectionHeader(
        f'Case {number}: {title}',
        subtitle=f'System: {system}',
        color=color,
        width=PAGE_W - 4*cm
    ))
    story.append(Spacer(1, 0.3*cm))

    # flowchart
    story.append(Paragraph('Diagnostic Flowchart', H3))
    story.append(Spacer(1, 0.15*cm))
    fc = FlowChart(flowchart_steps, width=PAGE_W-4*cm, font_size=8)
    story.append(fc)
    story.append(Spacer(1, 0.3*cm))

    # labs
    if labs_rows:
        story.append(Paragraph('Key Lab Findings', H3))
        story.append(Spacer(1, 0.1*cm))
        story.append(info_table(labs_rows, header_color=color))
        story.append(Spacer(1, 0.3*cm))

    # key points
    story.append(Paragraph('Key Points to Remember', H3))
    for kp in key_points:
        story.append(Paragraph(f'• {kp}', BULLET))
    story.append(Spacer(1, 0.2*cm))

    if mnemonics:
        story.append(colored_box_para(f'<b>Mnemonic:</b> {mnemonics}',
                                       bg=C_ORANGE_LT, fg=C_ORANGE))
        story.append(Spacer(1, 0.2*cm))

    if note:
        story.append(colored_box_para(f'<b>Exam Tip:</b> {note}',
                                       bg=C_PURPLE_LT, fg=C_PURPLE))
        story.append(Spacer(1, 0.2*cm))

    story.append(HRFlowable(width='100%', thickness=0.5, color=HexColor('#E5E7EB')))
    story.append(PageBreak())


# ═══════════════════════════════════════════════════════════════════════════════
# BUILD THE PDF
# ═══════════════════════════════════════════════════════════════════════════════

def build():
    doc = SimpleDocTemplate(
        '/home/daytona/workspace/mbbs-study-pdf/MBBS_Case_Study_Summary.pdf',
        pagesize=A4,
        leftMargin=2*cm, rightMargin=2*cm,
        topMargin=2*cm, bottomMargin=2*cm,
        title='MBBS 1st Year Biochemistry Case Study Summary',
        author='Orris AI',
        subject='Case Studies with Diagnosis Flowcharts',
    )

    story = []

    # ── COVER ────────────────────────────────────────────────────────────────
    cover_page(story)

    # ── CASE 1: MI ────────────────────────────────────────────────────────────
    add_case(
        story, '1', 'Myocardial Infarction', 'Cardiology / Cardiac Enzymes',
        color=C_RED,
        flowchart_steps=[
            {'text': 'Severe retrosternal chest pain + Sweating + Hypertension', 'color': C_RED, 'type': 'oval'},
            {'text': 'ECG: ST-segment elevation (STEMI)', 'color': HexColor('#B91C1C')},
            {'text': 'Serum CK-MB elevated (>5% of Total CK)\nTotal CK elevated', 'color': HexColor('#991B1B')},
            {'text': 'LDH elevated + Flipped LDH pattern (LDH1 > LDH2)', 'color': C_ORANGE},
            {'text': 'SGOT elevated; SGPT normal/mildly elevated\n(rules out primary liver pathology)', 'color': HexColor('#92400E')},
            {'text': 'DIAGNOSIS: ACUTE MYOCARDIAL INFARCTION', 'color': C_NAVY, 'type': 'oval', 'tcolor': C_WHITE},
        ],
        labs_rows=[
            ['Parameter',       'Result',       'Normal',         'Interpretation'],
            ['Serum CK',        '1150 IU/L',    '30-200 IU/L',    '↑↑ Elevated'],
            ['Serum CK-MB',     '455 IU/L',     '<5% total CK',   '↑↑↑ ~40% - CARDIAC SOURCE'],
            ['LDH',             '296 IU/L',     '100-225 IU/L',   '↑ Elevated'],
            ['SGOT (AST)',       '106 IU/L',     '10-40 IU/L',     '↑ Elevated'],
            ['SGPT (ALT)',       '25 IU/L',      '7-40 IU/L',      'Normal'],
        ],
        key_points=[
            'CK isoenzymes: CK-MM (skeletal), CK-MB (cardiac), CK-BB (brain)',
            'CK-MB rises 3-6h, peaks 12-24h, normalizes 48-72h after MI',
            'CK-MB index (CK-MB/Total CK × 100) >5-6% = diagnostic of MI',
            'Flipped LDH = LDH1 > LDH2 (normal: LDH2 > LDH1); appears day 2-3, persists 7-14 days',
            'Most specific cardiac markers: Troponin I and Troponin T',
            'SGOT elevated in MI (not liver); SGPT is more liver-specific',
        ],
        mnemonics='CK-MB = Cardiac Killer MB | Troponin = GOLD STANDARD for MI',
        note='In exam: Always mention CK-MB index (%) not just absolute value. Troponins are the gold standard - but CK-MB is still asked for 1st year.'
    )

    # ── CASE 2: PANCREATITIS ──────────────────────────────────────────────────
    add_case(
        story, '2', 'Acute Pancreatitis', 'GI / Pancreatic Enzymes',
        color=C_ORANGE,
        flowchart_steps=[
            {'text': 'Severe epigastric pain radiating to BACK + Alcohol history', 'color': C_ORANGE, 'type': 'oval'},
            {'text': 'Shock (BP 90/60), Epigastric tenderness + guarding', 'color': HexColor('#B45309')},
            {'text': 'Serum Amylase >3× normal (1500 U/L)\nSerum Lipase >3× normal (3000 U/L)', 'color': HexColor('#92400E')},
            {'text': 'Hyperglycemia (380 mg/dL)\nIslets of Langerhans destruction', 'color': C_RED, 'tcolor': C_WHITE},
            {'text': 'Hypocalcemia (6.0 mg/dL)\nFat saponification by released lipases', 'color': HexColor('#1D4ED8'), 'tcolor': C_WHITE},
            {'text': 'DIAGNOSIS: ACUTE PANCREATITIS', 'color': C_NAVY, 'type': 'oval'},
        ],
        labs_rows=[
            ['Parameter',        'Result',     'Normal',         'Significance'],
            ['Serum Amylase',    '1500 U/L',   '40-140 U/L',     '↑↑↑ (10×) - Pancreatitis marker'],
            ['Serum Lipase',     '3000 U/L',   '10-140 U/L',     '↑↑↑ More specific; persists longer'],
            ['Plasma Glucose',   '380 mg/dL',  '70-100 mg/dL',   '↑↑ Islet cell destruction'],
            ['Serum Calcium',    '6.0 mg/dL',  '8.5-10.5 mg/dL', '↓↓ Fat saponification = poor prognosis'],
            ['Urine Sugar',      '+++',        'Negative',       'Glucosuria (exceeds renal threshold)'],
        ],
        key_points=[
            'Lipase is more specific than amylase; rises later but persists longer (7-14 days vs 2-4 days)',
            'Hypocalcemia mechanism: Lipases → fatty acids + glycerol → FA binds Ca²+ → calcium soaps',
            'Hypocalcemia in pancreatitis = poor prognosis (Ranson\'s criteria)',
            'Hyperglycemia: destruction of beta cells (insulin↓) + increased glucagon',
            'Both amylase and lipase >3× normal = diagnostic of acute pancreatitis',
        ],
        note='Exam favorite: WHY is calcium low in pancreatitis? Answer = Saponification of fat (Ca²+ chelation by fatty acids released by lipase activity on peripancreatic fat).'
    )

    # ── CASE 3: METABOLIC SYNDROME ────────────────────────────────────────────
    add_case(
        story, '3', 'Metabolic Syndrome', 'Endocrine / Metabolism',
        color=C_PURPLE,
        flowchart_steps=[
            {'text': 'Obese woman (BMI 32) + Hypertension (160/110)', 'color': C_PURPLE, 'type': 'oval'},
            {'text': 'Acanthosis nigricans (dark velvety skin)\n→ Sign of hyperinsulinemia', 'color': HexColor('#6D28D9')},
            {'text': 'Random blood sugar 210 mg/dL\n→ Hyperglycemia', 'color': C_RED, 'tcolor': C_WHITE},
            {'text': 'Sedentary lifestyle + Postmenopausal\nFatigue, polyuria, chest heaviness', 'color': HexColor('#7C3AED')},
            {'text': 'NCEP-ATP III: ≥3 of 5 criteria met\n(Obesity, HTN, Hyperglycemia + likely ↑TG + ↓HDL)', 'color': HexColor('#4C1D95')},
            {'text': 'DIAGNOSIS: METABOLIC SYNDROME', 'color': C_NAVY, 'type': 'oval'},
        ],
        labs_rows=[
            ['Component',              'Criterion',         'This Patient'],
            ['Central Obesity',        'BMI >30 or WC >88cm (F)', 'BMI 32 ✓'],
            ['Hypertension',           '≥130/85 mmHg',      '160/110 ✓'],
            ['Fasting Hyperglycemia',  '≥100 mg/dL',        'RBS 210 ✓'],
            ['Hypertriglyceridemia',   '≥150 mg/dL',        'Likely ✓'],
            ['Low HDL',                '<50 mg/dL (women)',  'Likely ✓'],
        ],
        key_points=[
            'Metabolic Syndrome = Syndrome X = Insulin Resistance Syndrome',
            'Diagnosed when ≥3 of 5 NCEP-ATP III criteria are met',
            'Insulin resistance: target cells fail to respond to insulin despite normal/high levels',
            'Acanthosis nigricans = skin sign of hyperinsulinemia',
            'Risks: T2DM (5×), CVD, NAFLD, PCOS, gout, sleep apnea',
            'GLUT-4 translocation is impaired in insulin resistance (skeletal muscle, adipose)',
        ],
        mnemonics='5 criteria: OHHFG - Obesity, Hypertension, Hyperglycemia, hyperlipidemia (↑TG), low HDL',
    )

    # ── CASE 4: VON GIERKE'S ──────────────────────────────────────────────────
    add_case(
        story, '4', "Von Gierke's Disease (GSD Type I)", 'Glycogen Storage / Carbohydrate Metabolism',
        color=C_TEAL,
        flowchart_steps=[
            {'text': 'Infant: doll-like face, fat cheeks, massive hepatomegaly + enlarged kidneys', 'color': C_TEAL, 'type': 'oval'},
            {'text': 'Severe fasting hypoglycemia (35 mg/dL)\nNo glucose release from liver', 'color': C_RED, 'tcolor': C_WHITE},
            {'text': 'Lactic acidosis (90 mg/dL)\nG6P → glycolysis → excess lactate', 'color': HexColor('#0F766E')},
            {'text': 'Hyperuricemia (10 mg/dL)\nPentose-P pathway ↑ + Lactate competes with urate excretion', 'color': HexColor('#B45309'), 'tcolor': C_WHITE},
            {'text': 'Hypertriglyceridemia (400 mg/dL)\nExcess G6P → lipogenesis', 'color': HexColor('#7C3AED'), 'tcolor': C_WHITE},
            {'text': 'Enzyme deficient: GLUCOSE-6-PHOSPHATASE\nGSD Type Ia', 'color': HexColor('#065F46')},
            {'text': 'DIAGNOSIS: VON GIERKE\'S DISEASE', 'color': C_NAVY, 'type': 'oval'},
        ],
        labs_rows=[
            ['Parameter',         'Result',      'Normal',          'Significance'],
            ['Fasting Glucose',   '35 mg/dL',    '70-110 mg/dL',    '↓↓↓ Severe hypoglycemia'],
            ['Lactate',           '90 mg/dL',    '4.5-14.4 mg/dL',  '↑↑↑ Lactic acidosis'],
            ['Uric Acid',         '10 mg/dL',    '<7 mg/dL',        '↑ Hyperuricemia'],
            ['Triglycerides',     '400 mg/dL',   '<150 mg/dL',      '↑↑ Hyperlipidemia'],
            ['ALT',               '140 IU/L',    '7-40 IU/L',       '↑ Liver cell damage'],
            ['Urine Glucose',     'Negative',    'Negative',        'Normal (NOT hyperglycemic)'],
        ],
        key_points=[
            'Enzyme: Glucose-6-phosphatase (G6Pase) in liver/kidney ER',
            'G6P cannot be dephosphorylated → no free glucose released → severe fasting hypoglycemia',
            'Both glycogenolysis AND gluconeogenesis are blocked (both produce G6P)',
            'Hypoglycemia + Lactic acidosis + Hyperuricemia + Hypertriglyceridemia = classic tetrad',
            'Doll-like face = fat redistribution + hepatomegaly',
            'Treatment: frequent feeds, raw cornstarch (slow glucose release)',
        ],
        mnemonics='Von Gierke = No G6Pase = Glucose-6-P piles up = "Got 6 Problems": Hypoglycemia, Lactic acidosis, Hyperuricemia, Hypertriglyceridemia, Hepatomegaly, Renal enlargement',
        note='Urine glucose is NEGATIVE - key differentiator from diabetes. Glucose is low (not high) so nothing crosses renal threshold.'
    )

    # ── CASE 5: STARVATION KETOACIDOSIS ──────────────────────────────────────
    add_case(
        story, '5', 'Starvation Ketoacidosis', 'Metabolism / Acid-Base',
        color=HexColor('#D97706'),
        flowchart_steps=[
            {'text': 'Pregnant + prolonged vomiting (4 days) → Starvation state', 'color': HexColor('#D97706'), 'type': 'oval'},
            {'text': 'No food intake → ↓Insulin → ↑Glucagon\nFat mobilization from adipose', 'color': HexColor('#B45309')},
            {'text': 'Fatty acid β-oxidation → Excess Acetyl-CoA\nOxaloacetate depleted → Ketogenesis', 'color': HexColor('#92400E')},
            {'text': 'Serum glucose LOW (40 mg/dL) - starvation\nBenedict\'s NEGATIVE (no glucosuria)', 'color': C_GREEN, 'tcolor': C_WHITE},
            {'text': 'Rothera\'s POSITIVE (ketone bodies in urine)\npH 7.2, HCO₃ 15 mEq/L → Metabolic acidosis', 'color': C_RED, 'tcolor': C_WHITE},
            {'text': 'DIAGNOSIS: STARVATION KETOACIDOSIS\n(Hyperemesis Gravidarum)', 'color': C_NAVY, 'type': 'oval'},
        ],
        labs_rows=[
            ['Test',             'Result',        'Interpretation'],
            ['Serum Glucose',    '40 mg/dL',      '↓↓ Hypoglycemia (starvation)'],
            ['Blood pH',         '7.2',           '↓ Acidosis (normal 7.35-7.45)'],
            ['Serum HCO₃',       '15 mEq/L',      '↓ Metabolic acidosis'],
            ['Benedict\'s (urine)', 'Negative',   'No glucosuria = distinguishes from DKA'],
            ['Rothera\'s (urine)',  'Positive',    'Ketone bodies present'],
            ['Anion Gap',        'Elevated',      'Unmeasured ketoanions ↑'],
        ],
        key_points=[
            'KEY DIFFERENCE from DKA: Starvation ketosis has HYPOGLYCEMIA; DKA has HYPERGLYCEMIA',
            'Benedict\'s negative in starvation (no glucose) vs positive in DKA',
            'Rothera\'s test: sodium nitroprusside + ammonia → purple = acetoacetate/acetone',
            'Anion Gap = Na - (Cl + HCO₃); elevated in ketoacidosis due to ketoanions',
            'High Anion Gap Metabolic Acidosis: MUDPILES - Methanol, Uremia, DKA, Paraldehyde, Isoniazid, Lactic acidosis, Ethylene glycol, Salicylates',
        ],
        mnemonics='Starvation vs DKA: "Starvation = Sugar Low; DKA = Sugar HIGH - both have ketones"',
        note='Anion gap is ELEVATED in both starvation ketosis and DKA because both generate unmeasured ketoanions.'
    )

    # ── CASE 6: GOUT ──────────────────────────────────────────────────────────
    add_case(
        story, '6', 'Gout (Hyperuricemia)', 'Purine Metabolism',
        color=HexColor('#7C3AED'),
        flowchart_steps=[
            {'text': 'Heavy alcohol + purine-rich meal → Acute joint pain\nRight great toe (1st MTP joint) - Podagra', 'color': HexColor('#7C3AED'), 'type': 'oval'},
            {'text': 'Serum Uric Acid 17.2 mg/dL\n(Normal: <7.0 mg/dL in males) - VERY HIGH', 'color': HexColor('#6D28D9')},
            {'text': 'Synovial fluid: SODIUM URATE CRYSTALS\n(negatively birefringent, needle-shaped)', 'color': HexColor('#4C1D95')},
            {'text': 'Alcohol → ↑Lactate → Competes with urate for renal tubular secretion\n→ ↓Uric acid excretion', 'color': HexColor('#5B21B6')},
            {'text': 'Other labs: FBS, Urea, Creatinine normal\n→ Primary Gout', 'color': C_GREEN, 'tcolor': C_WHITE},
            {'text': 'DIAGNOSIS: ACUTE GOUTY ARTHRITIS', 'color': C_NAVY, 'type': 'oval'},
        ],
        labs_rows=[
            ['Investigation',      'Result',      'Normal',        'Interpretation'],
            ['Fasting Blood Sugar','97 mg/dL',    '70-100 mg/dL',  'Normal'],
            ['Blood Urea',         '30 mg/dL',    '10-40 mg/dL',   'Normal'],
            ['Serum Creatinine',   '0.9 mg/dL',   '0.6-1.2 mg/dL', 'Normal - No renal failure'],
            ['Serum Uric Acid',    '17.2 mg/dL',  '<7.0 mg/dL (M)','↑↑↑ Severe hyperuricemia'],
            ['Synovial fluid',     'Urate crystals','Absent',       'GOLD STANDARD - confirms gout'],
        ],
        key_points=[
            'Gout = crystal arthropathy due to monosodium urate deposition in joints',
            'Most common site: 1st metatarsophalangeal joint (podagra)',
            'Alcohol raises uric acid via: 1) Lactate competes with urate at renal tubule, 2) Beer contains purines',
            'Treatment - Acute: NSAIDs, Colchicine (inhibits microtubules → blocks neutrophil migration)',
            'Treatment - Long-term: Allopurinol (xanthine oxidase inhibitor) → blocks uric acid synthesis',
            'Tophus = urate crystal deposits in soft tissue (ear, elbow, Achilles tendon)',
        ],
        mnemonics='Allopurinol = ALL-O-PURINOL = blocks ALL purine → uric acid conversion (xanthine oxidase inhibitor)',
        note='Colchicine mechanism: inhibits tubulin polymerization → prevents neutrophil chemotaxis to urate crystals → anti-inflammatory. NOT an analgesic.'
    )

    # ── JAUNDICE COMPARISON PAGE ───────────────────────────────────────────────
    story.append(SectionHeader(
        'Cases 7-9: Jaundice - Comparative Analysis',
        subtitle='Hemolytic vs Hepatic vs Obstructive',
        color=HexColor('#B45309'),
        width=PAGE_W - 4*cm
    ))
    story.append(Spacer(1, 0.4*cm))

    story.append(Paragraph('Jaundice Diagnosis Flowchart', H3))
    story.append(Spacer(1, 0.1*cm))

    jaundice_fc = FlowChart([
        {'text': 'Patient with Jaundice (yellow skin/sclera)', 'color': HexColor('#B45309'), 'type': 'oval'},
        {'text': 'Measure: Total Bilirubin, Direct (Conjugated), Indirect (Unconjugated)\n+ ALP, SGOT, SGPT + Urine & Stool examination', 'color': HexColor('#92400E')},
        {'text': 'Which bilirubin is predominantly elevated?', 'color': HexColor('#78350F'), 'type': 'diamond'},
        {'text': 'INDIRECT >> DIRECT\n→ Hemolytic Jaundice\n• Normal ALP/SGOT/SGPT\n• Urine: No bile pigments (acholuric)\n• Stool: Dark (↑stercobilin)\n• Urobilinogen: ↑↑', 'color': HexColor('#B91C1C'), 'tcolor': C_WHITE},
        {'text': 'BOTH elevated (Mixed)\n→ Hepatic Jaundice\n• ↑↑↑ SGOT/SGPT (>10× normal)\n• Urine: Bile pigments +\n• Stool: Normal colour\n• Urobilinogen: Present', 'color': HexColor('#15803D'), 'tcolor': C_WHITE},
        {'text': 'DIRECT >> INDIRECT\n→ Obstructive Jaundice\n• ↑↑↑ ALP (>3×)\n• Urine: Dark (bile pigments +)\n• Stool: Clay/pale (no stercobilin)\n• Urobilinogen: ABSENT', 'color': HexColor('#1D4ED8'), 'tcolor': C_WHITE},
    ], width=PAGE_W-4*cm, font_size=7.5)
    story.append(jaundice_fc)
    story.append(Spacer(1, 0.3*cm))

    # comparison table
    story.append(Paragraph('Quick Comparison Table', H3))
    story.append(Spacer(1, 0.1*cm))
    comp_data = [
        ['Parameter',          'Hemolytic',     'Hepatic',        'Obstructive'],
        ['Direct Bilirubin',   '↑ (mild)',      '↑↑',             '↑↑↑'],
        ['Indirect Bilirubin', '↑↑↑',           '↑↑',             '↑ (mild)'],
        ['ALP',                'Normal',        'Mild ↑',         '↑↑↑ (>>3×)'],
        ['SGOT/SGPT',          'Normal',        '↑↑↑ (>>10×)',    'Mild ↑'],
        ['Urine Bile pigments','ABSENT',        'Present',        'Present'],
        ['Urine Urobilinogen', '↑↑↑',           'Present',        'ABSENT'],
        ['Stool colour',       'Dark',          'Normal',         'Clay/Pale'],
        ['Van den Bergh',      'Indirect +ve',  'Biphasic',       'Direct +ve'],
        ['Example',            'Mismatch transfusion', 'Viral hepatitis', 'Gallstones'],
    ]
    cw2 = [3.5*cm, 3.5*cm, 3.5*cm, 3.5*cm]
    ct = Table(comp_data, colWidths=cw2)
    ct.setStyle(TableStyle([
        ('BACKGROUND',    (0,0),  (-1,0),  C_NAVY),
        ('TEXTCOLOR',     (0,0),  (-1,0),  C_WHITE),
        ('BACKGROUND',    (0,1),  (0,-1),  HexColor('#F1F5F9')),
        ('TEXTCOLOR',     (0,1),  (0,-1),  C_NAVY),
        ('FONTNAME',      (0,0),  (-1,0),  'Helvetica-Bold'),
        ('FONTNAME',      (0,1),  (0,-1),  'Helvetica-Bold'),
        ('FONTSIZE',      (0,0),  (-1,-1), 8),
        ('ROWBACKGROUNDS',(1,1),  (-1,-1), [C_WHITE, C_GRAY_LT]),
        ('BOX',           (0,0),  (-1,-1), 0.5, C_GRAY),
        ('INNERGRID',     (0,0),  (-1,-1), 0.3, HexColor('#E5E7EB')),
        ('TOPPADDING',    (0,0),  (-1,-1), 3),
        ('BOTTOMPADDING', (0,0),  (-1,-1), 3),
        ('LEFTPADDING',   (0,0),  (-1,-1), 5),
        ('ALIGN',         (0,0),  (-1,-1), 'CENTER'),
    ]))
    story.append(ct)
    story.append(Spacer(1, 0.3*cm))
    story.append(colored_box_para(
        '<b>Acholuric Jaundice:</b> Jaundice WITHOUT bile pigments in urine. Seen in hemolytic jaundice. '
        'Unconjugated bilirubin is bound to albumin (water-insoluble) → cannot be filtered → urine remains pale despite jaundice.',
        bg=C_RED_LT, fg=C_RED))
    story.append(Spacer(1, 0.2*cm))
    story.append(colored_box_para(
        '<b>Biphasic Jaundice (Hepatic):</b> Both direct AND indirect bilirubin elevated. '
        'Van den Bergh: both direct and indirect positive = "biphasic/prompt direct." SGOT:SGPT ratio <1 in viral hepatitis.',
        bg=C_GREEN_LT, fg=C_GREEN))
    story.append(PageBreak())

    # ── CASE 10-11: RENAL ────────────────────────────────────────────────────
    story.append(SectionHeader(
        'Cases 10-11: Renal Diseases',
        subtitle='Nephrotic Syndrome vs Nephritic Syndrome (Glomerulonephritis)',
        color=HexColor('#1D4ED8'),
        width=PAGE_W - 4*cm
    ))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('Nephrotic vs Nephritic - Diagnosis Flowchart', H3))
    renal_fc = FlowChart([
        {'text': 'Child with oedema + urinary abnormalities', 'color': HexColor('#1D4ED8'), 'type': 'oval'},
        {'text': 'Check: Urine protein, Blood urea/creatinine,\nSerum albumin, Cholesterol, Urine RBC', 'color': HexColor('#1E40AF')},
        {'text': 'Massive proteinuria >3.5 g/day?\nHypoalbuminaemia? Hypercholesterolaemia?', 'color': HexColor('#1D4ED8'), 'type': 'diamond'},
        {'text': 'YES → NEPHROTIC SYNDROME\n• Albumin <2.5 g/dL (very low)\n• Cholesterol >300 mg/dL\n• Urea/Creatinine: Normal initially\n• No hematuria\n• 8-year-old boy: Minimal Change Disease', 'color': HexColor('#1E40AF'), 'tcolor': C_WHITE},
        {'text': 'NO → Check hematuria, azotemia, history of infection', 'color': HexColor('#374151'), 'tcolor': C_WHITE},
        {'text': 'NEPHRITIC SYNDROME (APSGN)\n• Dark brown urine (hematuria)\n• Proteinuria mild (not massive)\n• Albumin near normal (3.2 g/dL)\n• ↑↑ Urea/Creatinine (azotemia)\n• History of strep skin infection\n• Benzidine test POSITIVE', 'color': HexColor('#B91C1C'), 'tcolor': C_WHITE},
    ], width=PAGE_W-4*cm, font_size=7.5)
    story.append(renal_fc)
    story.append(Spacer(1, 0.3*cm))

    neph_comp = [
        ['Feature',           'Nephrotic Syndrome',     'Nephritic Syndrome (APSGN)'],
        ['Proteinuria',       '>3.5 g/day (massive)',   'Mild (1-3 g/day)'],
        ['Serum Albumin',     '<2.5 g/dL (very low)',   'Near normal (3.2)'],
        ['Cholesterol',       '>300 mg/dL ↑↑',          'Normal (~200)'],
        ['Hematuria',         'Absent',                  'Dark brown urine ✓'],
        ['Azotemia',          'Initially normal',        'Urea 90, Creat 2.5 ↑↑'],
        ['Hypertension',      'Can occur',               'Yes (160/110)'],
        ['Pathology',         'GBM permeability ↑',     'Immune complex deposition'],
        ['Typical age',       '8-year-old boy',          '10-year-old girl'],
        ['Cause',             'Minimal change disease',  'Post-streptococcal'],
        ['Benzidine test',    'Negative',                'POSITIVE (blood)'],
    ]
    cn = [4*cm, 5.5*cm, 5.5*cm]
    nct = Table(neph_comp, colWidths=cn)
    nct.setStyle(TableStyle([
        ('BACKGROUND',    (0,0),  (-1,0),  HexColor('#1D4ED8')),
        ('TEXTCOLOR',     (0,0),  (-1,0),  C_WHITE),
        ('FONTNAME',      (0,0),  (-1,0),  'Helvetica-Bold'),
        ('BACKGROUND',    (0,1),  (0,-1),  HexColor('#F1F5F9')),
        ('FONTNAME',      (0,1),  (0,-1),  'Helvetica-Bold'),
        ('FONTSIZE',      (0,0),  (-1,-1), 8),
        ('ROWBACKGROUNDS',(1,1),  (-1,-1), [C_WHITE, C_GRAY_LT]),
        ('BOX',           (0,0),  (-1,-1), 0.5, C_GRAY),
        ('INNERGRID',     (0,0),  (-1,-1), 0.3, HexColor('#E5E7EB')),
        ('TOPPADDING',    (0,0),  (-1,-1), 3),
        ('BOTTOMPADDING', (0,0),  (-1,-1), 3),
        ('LEFTPADDING',   (0,0),  (-1,-1), 5),
        ('ALIGN',         (1,0),  (-1,-1), 'CENTER'),
    ]))
    story.append(neph_comp[0:0])
    story.append(nct)
    story.append(Spacer(1, 0.3*cm))
    story.append(colored_box_para(
        '<b>Hypercholesterolemia in Nephrotic Syndrome:</b> Low albumin → low oncotic pressure → liver overcompensates '
        'by synthesizing all proteins including VLDL/LDL → hyperlipidemia. Also: loss of LPL cofactors → impaired clearance.',
        bg=C_LIGHT_BLU, fg=C_BLUE))
    story.append(Spacer(1, 0.2*cm))
    story.append(colored_box_para(
        '<b>Benzidine Test Principle:</b> Hemoglobin has pseudoperoxidase activity. In presence of H₂O₂, hemoglobin '
        'oxidizes benzidine (colorless) → blue-green color. Confirms hematuria.',
        bg=C_RED_LT, fg=C_RED))
    story.append(PageBreak())

    # ── CASE 12: THYROID ─────────────────────────────────────────────────────
    add_case(
        story, '12', 'Hyperthyroidism (Graves\' Disease)', 'Endocrinology / Thyroid',
        color=HexColor('#D97706'),
        flowchart_steps=[
            {'text': 'Weight loss + Increased appetite + Palpitations + Sweating + Exophthalmos', 'color': HexColor('#D97706'), 'type': 'oval'},
            {'text': 'Pulse 100/min (tachycardia) + Enlarged thyroid (goiter)', 'color': HexColor('#B45309')},
            {'text': 'TFT: Free T3 ↑↑, Free T4 ↑↑\nTSH ↓↓ (suppressed by negative feedback)', 'color': HexColor('#92400E')},
            {'text': 'TSH Receptor Antibodies (TSI)\nAutoimmune stimulation of thyroid = Graves\'', 'color': HexColor('#78350F')},
            {'text': 'Exophthalmos: TSI cross-react with retro-orbital fibroblasts\n→ GAG accumulation → proptosis', 'color': C_BLUE, 'tcolor': C_WHITE},
            {'text': 'DIAGNOSIS: HYPERTHYROIDISM (GRAVES\')', 'color': C_NAVY, 'type': 'oval'},
        ],
        labs_rows=[
            ['Parameter',    'Hyperthyroid',  'Hypothyroid',    'Normal'],
            ['TSH',          '↓↓ (low)',      '↑↑ (high)',      '0.4-4.0 mIU/L'],
            ['Free T3',      '↑↑',            '↓',              '2.3-4.2 pg/mL'],
            ['Free T4',      '↑↑',            '↓',              '0.8-1.8 ng/dL'],
            ['Total T4',     '↑',             '↓',              '4.5-12.5 µg/dL'],
            ['BMR',          '↑↑ (elevated)', '↓ (reduced)',    'Baseline'],
        ],
        key_points=[
            'TSH is the BEST screening test for thyroid disease; most sensitive indicator',
            'Free T3/T4 more accurate than total (not affected by TBG changes - pregnancy, OCP)',
            'T3 stimulates Na+/K+-ATPase → ↑ BMR → weight loss, heat intolerance, sweating',
            'Tachycardia: T3 upregulates β-adrenergic receptors + directly stimulates SA node',
            'Exophthalmos unique to Graves\' (autoimmune); separate from thyroid hormone levels',
            'Weight loss despite normal/increased appetite = hallmark of hyperthyroidism',
        ],
        mnemonics='Hyper thyroid: SWEATING - Sweating, Weight loss, Eyes (proptosis), Agitation, Tachycardia, Irritability, ↑appetite, Nervousness, Goitre',
        note='Free T3/T4 advantage: NOT affected by TBG levels. Pregnancy/OCP increase TBG → Total T4 appears high even in euthyroid. Free T4 stays normal = true status.'
    )

    # ── CASE 13: DKA + ACID BASE ─────────────────────────────────────────────
    story.append(SectionHeader(
        'Cases 13-14: DKA and Acid-Base Disorders',
        subtitle='Metabolic Acidosis | Respiratory Acidosis | Respiratory Alkalosis',
        color=C_RED,
        width=PAGE_W - 4*cm
    ))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('Acid-Base Diagnosis Flowchart', H3))
    ab_fc = FlowChart([
        {'text': 'Measure: Blood pH, pCO₂, HCO₃', 'color': C_RED, 'type': 'oval'},
        {'text': 'pH < 7.35 = ACIDOSIS\npH > 7.45 = ALKALOSIS', 'color': HexColor('#B91C1C'), 'type': 'diamond'},
        {'text': 'Acidosis: Is pCO₂ HIGH or HCO₃ LOW?', 'color': HexColor('#991B1B'), 'type': 'diamond'},
        {'text': 'pCO₂ ↑↑ (>45) = RESPIRATORY ACIDOSIS\n(e.g., Asthma, COPD, pCO₂=82)\nKidney compensates: ↑HCO₃ reabsorption\nTreat: Bronchodilators, assisted ventilation', 'color': HexColor('#7F1D1D'), 'tcolor': C_WHITE},
        {'text': 'HCO₃ ↓↓ (<22) = METABOLIC ACIDOSIS\n(e.g., DKA: pH 7.25, HCO₃ 15)\nLung compensates: Kussmaul\'s breathing ↓pCO₂\nHigh Anion Gap: DKA, Lactic acidosis, Uremia', 'color': HexColor('#1D4ED8'), 'tcolor': C_WHITE},
        {'text': 'Alkalosis: pCO₂ LOW = RESPIRATORY ALKALOSIS\n(e.g., Anxiety/hyperventilation: pH 7.6, pCO₂ 20)\n↓Ionized Ca²+ → Tetany/tingling\nKidney compensates: ↓HCO₃', 'color': C_GREEN, 'tcolor': C_WHITE},
    ], width=PAGE_W-4*cm, font_size=7.5)
    story.append(ab_fc)
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('Quick Acid-Base Summary Table', H3))
    ab_data = [
        ['Disorder',          'pH',   'pCO₂',  'HCO₃', 'Cause',              'Compensation'],
        ['Resp. Acidosis',    '↓',    '↑↑',    '↑',    'Asthma, COPD',       'Renal: ↑HCO₃ retain'],
        ['Resp. Alkalosis',   '↑',    '↓↓',    '↓',    'Anxiety, altitude',   'Renal: ↓HCO₃ retain'],
        ['Metab. Acidosis',   '↓',    '↓',     '↓↓',   'DKA, lactic acid',    'Lung: Kussmaul\'s ↓pCO₂'],
        ['Metab. Alkalosis',  '↑',    '↑',     '↑↑',   'Vomiting, diuretics', 'Lung: ↓ventilation ↑pCO₂'],
    ]
    ab_t = Table(ab_data, colWidths=[3*cm, 1.2*cm, 1.3*cm, 1.3*cm, 4*cm, 4.2*cm])
    ab_t.setStyle(TableStyle([
        ('BACKGROUND',    (0,0), (-1,0), C_NAVY),
        ('TEXTCOLOR',     (0,0), (-1,0), C_WHITE),
        ('FONTNAME',      (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE',      (0,0), (-1,-1), 8),
        ('ROWBACKGROUNDS',(0,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
        ('BOX',           (0,0), (-1,-1), 0.5, C_GRAY),
        ('INNERGRID',     (0,0), (-1,-1), 0.3, HexColor('#E5E7EB')),
        ('TOPPADDING',    (0,0), (-1,-1), 3),
        ('BOTTOMPADDING', (0,0), (-1,-1), 3),
        ('LEFTPADDING',   (0,0), (-1,-1), 5),
        ('ALIGN',         (1,0), (4,-1), 'CENTER'),
    ]))
    story.append(ab_t)
    story.append(Spacer(1, 0.3*cm))
    story.append(colored_box_para(
        '<b>Kussmaul\'s Breathing (DKA):</b> Deep rapid respiration = respiratory compensation for metabolic acidosis. '
        'Blows off CO₂ → reduces pCO₂ → raises pH toward normal. Patients have fruity/acetone breath (exhaled acetone).',
        bg=C_RED_LT, fg=C_RED))
    story.append(Spacer(1, 0.2*cm))
    story.append(colored_box_para(
        '<b>Why ionized Ca²+ falls in respiratory alkalosis:</b> Alkalosis → Albumin loses H⁺ → albumin becomes more '
        'negatively charged → binds more Ca²+ → ionized Ca²+ decreases → tetany, tingling.',
        bg=C_ORANGE_LT, fg=C_ORANGE))
    story.append(Spacer(1, 0.2*cm))
    story.append(colored_box_para(
        '<b>Anion Gap = Na⁺ - (Cl⁻ + HCO₃⁻). Normal: 8-16 mEq/L.</b> HIGH in: DKA, Lactic acidosis, Uremia, '
        'Methanol, Salicylates (MUDPILES). NORMAL in: Diarrhea, RTA (hyperchloremic acidosis).',
        bg=C_LIGHT_BLU, fg=C_BLUE))
    story.append(PageBreak())

    # ── CASE 15: NAFLD ───────────────────────────────────────────────────────
    add_case(
        story, '15', 'NAFLD (Non-Alcoholic Fatty Liver Disease)', 'Hepatology / Lipid Metabolism',
        color=C_TEAL,
        flowchart_steps=[
            {'text': 'Obese (BMI >30) + T2DM + Hypertension + NO ALCOHOL\nMetabolic Syndrome background', 'color': C_TEAL, 'type': 'oval'},
            {'text': 'Insulin resistance → Hyperinsulinemia\n↑ De novo lipogenesis in liver + ↓ β-oxidation', 'color': HexColor('#0F766E')},
            {'text': 'Excess TG accumulates in hepatocytes → STEATOSIS\nSimple fatty liver = Grade I-II on ultrasound', 'color': HexColor('#065F46')},
            {'text': 'Oxidative stress + TNF-α, IL-6 → hepatocyte apoptosis\nNASH = Steatosis + INFLAMMATION', 'color': C_ORANGE, 'tcolor': C_WHITE},
            {'text': 'ALT 108, AST 95 (ALT > AST)\nHbA1c 8.4%, Hypertriglyceridemia\nUSG: Grade II echogenic (fatty) liver', 'color': HexColor('#1D4ED8'), 'tcolor': C_WHITE},
            {'text': 'DIAGNOSIS: NAFLD / NASH', 'color': C_NAVY, 'type': 'oval'},
        ],
        labs_rows=[
            ['Parameter',  'Result',     'Significance'],
            ['ALT',        '108 U/L',    '↑ Cytoplasmic enzyme - hepatocellular damage'],
            ['AST',        '95 U/L',     '↑ Mitochondrial enzyme - hepatocellular damage'],
            ['ALT:AST',    '>1 (1.13)',  'ALT > AST in NAFLD (vs AST > ALT in alcohol)'],
            ['HbA1c',      '8.4%',       'Poor glycemic control → drives lipogenesis'],
            ['TG',         'Elevated',   'Dyslipidemia of insulin resistance'],
            ['USG',        'Grade II',   'Echogenic liver = fat infiltration'],
        ],
        key_points=[
            'NAFLD requires ABSENCE of significant alcohol consumption (<20g/day women, <30g/day men)',
            'ALT > AST in NAFLD; AST:ALT >2:1 in ALCOHOLIC liver disease',
            'Mechanism: Insulin resistance → ↑fatty acids → hepatic steatosis → NASH → cirrhosis → HCC',
            'HbA1c reflects 3-month average blood glucose; 8.4% = prolonged poor control',
            'Treatment: Weight loss (10%+ reduces liver fat), diabetes control, exercise',
        ],
        note='Key differentiator: In NAFLD ALT>AST. In ALCOHOLIC liver disease AST>ALT (ratio >2:1). No alcohol history is essential for NAFLD diagnosis.'
    )

    # ── AMINO ACIDOPATHIES ────────────────────────────────────────────────────
    story.append(SectionHeader(
        'Case 16: Amino Acid Disorders - PKU, Alkaptonuria, Homocystinuria, MSUD',
        subtitle='Inborn Errors of Amino Acid Metabolism',
        color=HexColor('#4F46E5'),
        width=PAGE_W - 4*cm
    ))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('PKU Diagnosis Flowchart', H3))
    pku_fc = FlowChart([
        {'text': 'Infant: Mental retardation + Seizures + Delayed milestones + Pale skin', 'color': HexColor('#4F46E5'), 'type': 'oval'},
        {'text': 'Serum phenylalanine >> 50 mg/dL (normal <1.2)\nUrine: phenylpyruvate +++ , phenylacetate +++', 'color': HexColor('#4338CA')},
        {'text': 'ENZYME DEFICIENT: Phenylalanine Hydroxylase (PAH)\n+ cofactor Tetrahydrobiopterin (BH4)', 'color': HexColor('#3730A3')},
        {'text': 'Phenylalanine → Phenylpyruvate (toxic)\n→ Brain damage, seizures', 'color': C_RED, 'tcolor': C_WHITE},
        {'text': 'Hypopigmentation: Tyr deficient → ↓Melanin\n(Phenylalanine → Tyrosine is blocked)', 'color': HexColor('#6D28D9'), 'tcolor': C_WHITE},
        {'text': 'DIAGNOSIS: PHENYLKETONURIA (PKU)\nTreatment: Phenylalanine-restricted diet', 'color': C_NAVY, 'type': 'oval'},
    ], width=PAGE_W-4*cm, font_size=7.5)
    story.append(pku_fc)
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('Comparison: Major Amino Acid Disorders', H3))
    aa_data = [
        ['Disorder',       'Enzyme Deficient',          'Urine Test',          'Key Feature'],
        ['PKU',            'Phenylalanine Hydroxylase',  'Ferric chloride (green/blue)\nPhenylpyruvate +++', 'Mental retardation\nPale skin'],
        ['Alkaptonuria',   'Homogentisate Oxidase',      'Ferric chloride +ve\nDarkens on standing', 'Dark urine\nOchronosis (adults)'],
        ['Homocystinuria', 'Cystathionine β-Synthase',   'Cyanide nitroprusside +', 'Ectopia lentis\nThromboembolism'],
        ['MSUD',           'BCKDH complex',              'DNPH test (keto acids)', 'Maple syrup urine\nBCCA elevated'],
        ['Albinism',       'Tyrosinase',                 'None',                'No melanin\nPhotosensitivity'],
        ['Cystinuria',     'Renal COLA transporter',     'Cyanide nitroprusside +\nHexagonal crystals', 'Kidney stones\nCOLA amino acids ↑'],
    ]
    aa_t = Table(aa_data, colWidths=[3.2*cm, 3.8*cm, 3.8*cm, 4.2*cm])
    aa_t.setStyle(TableStyle([
        ('BACKGROUND',    (0,0),  (-1,0),  HexColor('#4F46E5')),
        ('TEXTCOLOR',     (0,0),  (-1,0),  C_WHITE),
        ('FONTNAME',      (0,0),  (-1,0),  'Helvetica-Bold'),
        ('FONTSIZE',      (0,0),  (-1,-1), 7.5),
        ('ROWBACKGROUNDS',(0,1),  (-1,-1), [C_WHITE, C_GRAY_LT]),
        ('BOX',           (0,0),  (-1,-1), 0.5, C_GRAY),
        ('INNERGRID',     (0,0),  (-1,-1), 0.3, HexColor('#E5E7EB')),
        ('TOPPADDING',    (0,0),  (-1,-1), 3),
        ('BOTTOMPADDING', (0,0),  (-1,-1), 3),
        ('LEFTPADDING',   (0,0),  (-1,-1), 5),
        ('VALIGN',        (0,0),  (-1,-1), 'TOP'),
    ]))
    story.append(aa_t)
    story.append(Spacer(1, 0.2*cm))
    story.append(colored_box_para(
        '<b>COLA in Cystinuria:</b> Cystine, Ornithine, Lysine, Arginine - dibasic amino acids. Renal transporter defect → all 4 in urine. '
        'Only cystine precipitates (least soluble) → hexagonal crystals → kidney stones.',
        bg=C_LIGHT_BLU, fg=C_BLUE))
    story.append(PageBreak())

    # ── CASE 17: KWASHIORKOR ──────────────────────────────────────────────────
    story.append(SectionHeader(
        'Case 17: Protein Energy Malnutrition',
        subtitle='Kwashiorkor vs Marasmus',
        color=HexColor('#B45309'),
        width=PAGE_W - 4*cm
    ))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('Kwashiorkor Diagnosis Flowchart', H3))
    kw_fc = FlowChart([
        {'text': '2-3 year old child, abruptly weaned, diet = mainly carbohydrates\n(rice gruel, boiled potatoes)', 'color': HexColor('#B45309'), 'type': 'oval'},
        {'text': 'Pitting edema (legs/hands/face)\nDistended abdomen, hepatomegaly', 'color': HexColor('#92400E')},
        {'text': 'Serum albumin ↓↓ (1.8 g/dL)\nSerum protein ↓ (4 g/dL)', 'color': HexColor('#78350F')},
        {'text': 'Low albumin → Low oncotic pressure\n→ Fluid leaks to interstitium → EDEMA', 'color': C_BLUE, 'tcolor': C_WHITE},
        {'text': 'Fatty liver: ↓Apolipoprotein B → VLDL not formed\n→ TG accumulates in hepatocytes', 'color': C_RED, 'tcolor': C_WHITE},
        {'text': 'Hair: depigmented (flag sign), easily pluckable\nSkin: flaky paint dermatosis\nAnemia: Hb 6.5 g/dL', 'color': HexColor('#374151'), 'tcolor': C_WHITE},
        {'text': 'DIAGNOSIS: KWASHIORKOR\nTreat: F-75 → F-100 → RUTF', 'color': C_NAVY, 'type': 'oval'},
    ], width=PAGE_W-4*cm, font_size=7.5)
    story.append(kw_fc)
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('Kwashiorkor vs Marasmus Comparison', H3))
    pem_data = [
        ['Feature',           'Kwashiorkor',                'Marasmus'],
        ['Definition',        'Protein deficiency',         'Total calorie deficiency'],
        ['Edema',             'YES (hallmark)',              'NO'],
        ['Body weight',       'Near normal/slightly low',    'Very low (<60% expected)'],
        ['Serum albumin',     'Very low (<2.5 g/dL)',        'Low but less severe'],
        ['Fatty liver',       'YES (↓ApoB)',                 'NO'],
        ['Appearance',        'Moon face, pot belly',        'Skin and bones, wasted'],
        ['Hair changes',      'Depigmented, flag sign',      'Sparse, dull'],
        ['Skin',              'Flaky paint dermatosis',      'Loose, wrinkled'],
        ['Age',               '6 months-3 years',           '< 1 year'],
        ['Treatment',         'F-75, F-100, RUTF',          'F-75, F-100, RUTF'],
    ]
    pem_t = Table(pem_data, colWidths=[4.5*cm, 5.5*cm, 5*cm])
    pem_t.setStyle(TableStyle([
        ('BACKGROUND',    (0,0),  (-1,0),  HexColor('#B45309')),
        ('TEXTCOLOR',     (0,0),  (-1,0),  C_WHITE),
        ('FONTNAME',      (0,0),  (-1,0),  'Helvetica-Bold'),
        ('FONTSIZE',      (0,0),  (-1,-1), 8),
        ('ROWBACKGROUNDS',(0,1),  (-1,-1), [C_WHITE, C_GRAY_LT]),
        ('BOX',           (0,0),  (-1,-1), 0.5, C_GRAY),
        ('INNERGRID',     (0,0),  (-1,-1), 0.3, HexColor('#E5E7EB')),
        ('TOPPADDING',    (0,0),  (-1,-1), 3),
        ('BOTTOMPADDING', (0,0),  (-1,-1), 3),
        ('LEFTPADDING',   (0,0),  (-1,-1), 5),
        ('VALIGN',        (0,0),  (-1,-1), 'TOP'),
    ]))
    story.append(pem_t)
    story.append(Spacer(1, 0.2*cm))
    story.append(colored_box_para(
        '<b>Protein Sparing Effect:</b> Adequate carbohydrates/fats spare protein from being used as energy → proteins used for synthesis. '
        'In Kwashiorkor: despite adequate calories (carbs), protein is absent → no protein available for synthesis → edema, fatty liver.',
        bg=C_ORANGE_LT, fg=C_ORANGE))
    story.append(PageBreak())

    # ── MINOR CASES VITAMIN DEFICIENCIES ─────────────────────────────────────
    story.append(SectionHeader(
        'Minor Cases: Vitamin Deficiencies',
        subtitle='Vitamins A, D, C, B1, B3, B12/Folate',
        color=C_GREEN,
        width=PAGE_W - 4*cm
    ))
    story.append(Spacer(1, 0.3*cm))

    vit_data = [
        ['Vitamin',  'Deficiency Disease',  'Key Biochemistry',          'Clinical Features',         'Diagnosis'],
        ['A\n(Retinol)',   'Xerophthalmia\nNight blindness', '11-cis-retinal needed for rhodopsin (rod cells)', 'Night blindness (first sign)\nBitot\'s spots\nKeratomalacia\nDry rough skin', 'Low serum retinol\nLow RBP'],
        ['D\n(Calcitriol)', 'Rickets (children)\nOsteomalacia (adults)', 'Calcitriol regulates Ca²+/PO₄ absorption\n↓Ca, ↓PO₄ → ↓bone mineralization', 'Bow legs, pigeon chest\nRachitic rosary\nDelayed dentition\nHarrison\'s sulcus', 'Low calcitriol\nLow Ca/PO₄\n↑ALP (osteoblast)'],
        ['C\n(Ascorbic acid)', 'Scurvy', 'Cofactor for prolyl/lysyl hydroxylase\n→ Defective collagen synthesis', 'Bleeding gums\nPerifollicular hemorrhages\nCorkscrew hairs\nPoor wound healing\nAnemia', 'Low blood vit. C\n<0.2 mg/dL'],
        ['B1\n(Thiamine)', 'Beriberi\nWernicke-Korsakoff', 'TPP coenzyme for:\nPyruvate DH\nα-KG DH\nTransketolase', 'Wet: edema, cardiac failure\nDry: peripheral neuropathy\nWK: ophthalmoplegia, ataxia, confusion', 'Low RBC transketolase\nPolished rice diet'],
        ['B3\n(Niacin)', 'Pellagra', 'NAD+/NADP+ synthesis\n60mg Trp = 1mg Niacin', '4 Ds: Dermatitis (sun-exposed)\nDiarrhea, Dementia, Death\nCasal\'s necklace', 'Maize/corn diet\nLow urine N-methyl nicotinamide'],
        ['B12 + Folate', 'Megaloblastic Anemia', 'DNA synthesis: dUMP → dTMP\nB12: methylmalonyl-CoA mutase\nMethyl THF trap', 'High MCV\nHypersegmented neutrophils\nGlossitis, fatigue\nB12: subacute combined degeneration', 'Low B12 (<200 pg/mL)\nLow folate\n↑MCV, ↑homocysteine'],
    ]
    vit_t = Table(vit_data, colWidths=[1.5*cm, 2.3*cm, 3.8*cm, 4*cm, 3.4*cm])
    vit_t.setStyle(TableStyle([
        ('BACKGROUND',    (0,0),  (-1,0),  C_GREEN),
        ('TEXTCOLOR',     (0,0),  (-1,0),  C_WHITE),
        ('FONTNAME',      (0,0),  (-1,0),  'Helvetica-Bold'),
        ('FONTSIZE',      (0,0),  (-1,-1), 7),
        ('ROWBACKGROUNDS',(0,1),  (-1,-1), [C_WHITE, C_GREEN_LT]),
        ('BOX',           (0,0),  (-1,-1), 0.5, C_GRAY),
        ('INNERGRID',     (0,0),  (-1,-1), 0.3, HexColor('#E5E7EB')),
        ('TOPPADDING',    (0,0),  (-1,-1), 4),
        ('BOTTOMPADDING', (0,0),  (-1,-1), 4),
        ('LEFTPADDING',   (0,0),  (-1,-1), 4),
        ('VALIGN',        (0,0),  (-1,-1), 'TOP'),
    ]))
    story.append(vit_t)
    story.append(Spacer(1, 0.3*cm))
    story.append(colored_box_para(
        '<b>B12 vs Folate Deficiency:</b> Both cause megaloblastic anemia (high MCV). '
        'ONLY B12 deficiency causes neurological damage (subacute combined degeneration of spinal cord). '
        'Folate deficiency in pregnancy → neural tube defects. Never give folate alone without ruling out B12 deficiency.',
        bg=C_GREEN_LT, fg=C_GREEN))
    story.append(PageBreak())

    # ── MINOR CASES - ANEMIAS + MINERALS ─────────────────────────────────────
    story.append(SectionHeader(
        'Minor Cases: Anemias, Minerals & Miscellaneous',
        subtitle='Iron Deficiency | Tetany | Goitre | Fluorosis | Galactosemia',
        color=HexColor('#1D4ED8'),
        width=PAGE_W - 4*cm
    ))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('Iron Deficiency Anemia - Diagnosis Flowchart', H3))
    ida_fc = FlowChart([
        {'text': 'Young female: fatigue, breathlessness, brittle nails, hair fall, pica (ice chewing)', 'color': HexColor('#1D4ED8'), 'type': 'oval'},
        {'text': 'CBC: Low Hb, Low MCV (microcytic), Low MCH (hypochromic)', 'color': HexColor('#1E40AF')},
        {'text': 'Serum Ferritin LOW (8 ng/mL)\n= MOST SPECIFIC test for iron stores', 'color': HexColor('#1D4ED8')},
        {'text': 'Serum Iron LOW (25 mcg/dL)\nTIBC HIGH (iron binding sites unfilled)', 'color': HexColor('#374151'), 'tcolor': C_WHITE},
        {'text': 'DIAGNOSIS: IRON DEFICIENCY ANEMIA\nStages: 1) Depleted stores (↓ferritin)\n2) Latent IDA (↓iron, ↑TIBC)\n3) Frank IDA (↓Hb)', 'color': C_NAVY, 'type': 'oval'},
    ], width=PAGE_W-4*cm, font_size=7.5)
    story.append(ida_fc)
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('Minerals Summary: Tetany / Goitre / Fluorosis', H3))
    story.append(Spacer(1, 0.1*cm))
    min_data = [
        ['Condition',  'Cause',                   'Key Biochemistry',            'Clinical',              'Treatment'],
        ['Tetany\n(Post-thyroidectomy)', 'Accidental parathyroid removal → ↓PTH → ↓Ca²+', '↓Ionized Ca²+ → nerve hyperexcitability', 'Chvostek\'s sign\nTrousseau\'s sign\nCarpopedal spasm\nParesthesias', 'IV Ca gluconate (emergency)\nOral Ca + Calcitriol'],
        ['Goitre', 'Iodine deficiency (or Hashimoto\'s)', '↓Iodine → ↓T3/T4 → ↑TSH → thyroid hypertrophy', 'Neck swelling (moves on swallowing)\nHypothyroid symptoms\nCold intolerance, menstrual irregularity', 'Iodized salt\nLevothyroxine\nAnti-TPO for Hashimoto'],
        ['Fluorosis', 'Excess fluoride (drinking water >1.5 mg/L)', 'Fluoride inhibits ameloblasts\nF replaces OH in hydroxyapatite → fluorapatite', 'Mottled brown-black teeth\nSkeletal stiffness\n↑ALP (osteoblast)', 'Remove from fluoride source\nCa supplementation'],
    ]
    min_t = Table(min_data, colWidths=[2*cm, 3.2*cm, 3.5*cm, 3.5*cm, 2.8*cm])
    min_t.setStyle(TableStyle([
        ('BACKGROUND',    (0,0),  (-1,0),  HexColor('#1D4ED8')),
        ('TEXTCOLOR',     (0,0),  (-1,0),  C_WHITE),
        ('FONTNAME',      (0,0),  (-1,0),  'Helvetica-Bold'),
        ('FONTSIZE',      (0,0),  (-1,-1), 7),
        ('ROWBACKGROUNDS',(0,1),  (-1,-1), [C_WHITE, C_LIGHT_BLU]),
        ('BOX',           (0,0),  (-1,-1), 0.5, C_GRAY),
        ('INNERGRID',     (0,0),  (-1,-1), 0.3, HexColor('#E5E7EB')),
        ('TOPPADDING',    (0,0),  (-1,-1), 4),
        ('BOTTOMPADDING', (0,0),  (-1,-1), 4),
        ('LEFTPADDING',   (0,0),  (-1,-1), 4),
        ('VALIGN',        (0,0),  (-1,-1), 'TOP'),
    ]))
    story.append(min_t)
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph('Galactosemia & Other Carbohydrate Disorders', H3))
    gal_data = [
        ['Disorder',       'Enzyme Defect',           'Urine Test',              'Key Feature',          'Treatment'],
        ['Galactosemia',   'Galactose-1-P Uridylyltransferase (GALT)', 'Benedict\'s +ve\nMucic acid +ve\nGlucose -ve', 'Cataract\n(galactitol in lens)\nLiver damage', 'Lactose-free diet'],
        ['Von Gierke\'s',  'Glucose-6-Phosphatase',   'Urine glucose NEGATIVE',  'Severe hypoglycemia\nHepatomegaly', 'Frequent feeds\nCornstarch'],
    ]
    gal_t = Table(gal_data, colWidths=[2.5*cm, 3.5*cm, 3*cm, 3*cm, 3*cm])
    gal_t.setStyle(TableStyle([
        ('BACKGROUND',    (0,0),  (-1,0),  C_TEAL),
        ('TEXTCOLOR',     (0,0),  (-1,0),  C_WHITE),
        ('FONTNAME',      (0,0),  (-1,0),  'Helvetica-Bold'),
        ('FONTSIZE',      (0,0),  (-1,-1), 7),
        ('ROWBACKGROUNDS',(0,1),  (-1,-1), [C_WHITE, C_TEAL_LT]),
        ('BOX',           (0,0),  (-1,-1), 0.5, C_GRAY),
        ('INNERGRID',     (0,0),  (-1,-1), 0.3, HexColor('#E5E7EB')),
        ('TOPPADDING',    (0,0),  (-1,-1), 4),
        ('BOTTOMPADDING', (0,0),  (-1,-1), 4),
        ('LEFTPADDING',   (0,0),  (-1,-1), 4),
        ('VALIGN',        (0,0),  (-1,-1), 'TOP'),
    ]))
    story.append(gal_t)
    story.append(Spacer(1, 0.3*cm))
    story.append(colored_box_para(
        '<b>Cataract in Galactosemia:</b> Galactose accumulates → aldose reductase converts galactose → galactitol in the lens. '
        'Galactitol is osmotically active and cannot leave the lens → lens swells → cataract. Treatment: remove galactose from diet immediately.',
        bg=C_TEAL_LT, fg=C_TEAL))
    story.append(PageBreak())

    # ── PROSTATE + BREAST CARCINOMA ───────────────────────────────────────────
    story.append(SectionHeader(
        'Tumour Markers: Prostate & Breast Carcinoma',
        subtitle='PSA, CA 15-3, CEA, HER-2',
        color=C_NAVY,
        width=PAGE_W - 4*cm
    ))
    story.append(Spacer(1, 0.3*cm))

    tm_data = [
        ['Cancer',       'Primary Marker',   'Other Markers',                'Normal Value',         'Uses'],
        ['Prostate Ca',  'PSA',              'Free PSA/Total PSA ratio\nProstatic Acid Phosphatase (PAP)\nALP (bone mets)', '<4 ng/mL\n(>10 = malignancy likely)', 'Screening, staging\nMonitoring treatment\nDetect recurrence'],
        ['Breast Ca',    'CA 15-3',          'CA 27.29\nCEA\nHER-2/neu (ErbB2)\nER/PR receptors\nBRCA1/BRCA2', '<30 U/mL', 'Monitoring metastatic\nTreatment response\nHER-2 = trastuzumab target'],
    ]
    tm_t = Table(tm_data, colWidths=[2.5*cm, 3*cm, 4.5*cm, 2.5*cm, 2.5*cm])
    tm_t.setStyle(TableStyle([
        ('BACKGROUND',    (0,0),  (-1,0),  C_NAVY),
        ('TEXTCOLOR',     (0,0),  (-1,0),  C_WHITE),
        ('FONTNAME',      (0,0),  (-1,0),  'Helvetica-Bold'),
        ('FONTSIZE',      (0,0),  (-1,-1), 7.5),
        ('ROWBACKGROUNDS',(0,1),  (-1,-1), [C_WHITE, C_GRAY_LT]),
        ('BOX',           (0,0),  (-1,-1), 0.5, C_GRAY),
        ('INNERGRID',     (0,0),  (-1,-1), 0.3, HexColor('#E5E7EB')),
        ('TOPPADDING',    (0,0),  (-1,-1), 5),
        ('BOTTOMPADDING', (0,0),  (-1,-1), 5),
        ('LEFTPADDING',   (0,0),  (-1,-1), 5),
        ('VALIGN',        (0,0),  (-1,-1), 'TOP'),
    ]))
    story.append(tm_t)
    story.append(Spacer(1, 0.3*cm))
    story.append(colored_box_para(
        '<b>Definition of Tumour Marker:</b> A substance produced by tumour cells or by the body in response to cancer, '
        'detectable in blood/urine/tissue. Used for: Screening | Diagnosis | Monitoring treatment | Detecting recurrence | Prognosis. '
        'No marker is 100% specific - must be interpreted with clinical context.',
        bg=C_GRAY_LT, fg=C_NAVY))
    story.append(Spacer(1, 0.2*cm))
    story.append(colored_box_para(
        '<b>PSA:</b> Prostate Specific Antigen = serine protease produced by prostate epithelium. '
        'PSA <4 normal; 4-10 = "grey zone"; >10 = high malignancy risk. '
        'Low free/total PSA ratio (<10%) suggests malignancy. Can also be elevated in BPH, prostatitis.',
        bg=C_LIGHT_BLU, fg=C_BLUE))
    story.append(Spacer(1, 0.3*cm))

    # Final summary mnemonics page
    story.append(Paragraph('Master Mnemonic Summary', H2))
    story.append(Spacer(1, 0.1*cm))
    mnemo_data = [
        ['Topic',                       'Mnemonic / Key Point'],
        ['Essential Amino Acids (9)',    'PVT TIM HaLL: Phe, Val, Thr, Trp, Ile, Met, His, Arg(semi), Leu, Lys'],
        ['MUDPILES (High AG acidosis)',  'Methanol, Uremia, DKA, Propylene glycol, Isoniazid/Iron, Lactic acidosis, Ethylene glycol, Salicylates'],
        ['Metabolic Syndrome (5 criteria)', 'OHHFL: Obesity, Hypertension, Hyperglycemia, Fat (↑TG), Low HDL'],
        ['Pellagra 4 Ds',               'Dermatitis (sun-exposed), Diarrhea, Dementia, Death'],
        ['Gout treatment',              'ANCP: Acute=NSAIDs/Colchicine; Chronic=allopurinol (xanthine oxidase inhibitor)'],
        ['Jaundice differentials',      'H-H-O: Hemolytic(↑indirect, no bile in urine), Hepatic(both, ↑SGPT), Obstructive(↑direct, ↑ALP, clay stool)'],
        ['Von Gierke\'s tetrad',        'HLLU: Hypoglycemia, Lactic acidosis, ↑Lipids, Uric acid ↑'],
        ['COLA amino acids (Cystinuria)','Cystine, Ornithine, Lysine, Arginine'],
        ['Kwashiorkor vs Marasmus',     'K=edema(+), Protein deficient. M=wasted, Total calorie deficient'],
        ['DKA vs Starvation ketosis',   'DKA: HIGH glucose + ketones. Starvation: LOW glucose + ketones'],
        ['Acid-base primary changes',   'pH and pCO2 move OPPOSITE in respiratory; pH and HCO3 move SAME in metabolic'],
    ]
    mn_t = Table(mnemo_data, colWidths=[5*cm, 10*cm])
    mn_t.setStyle(TableStyle([
        ('BACKGROUND',    (0,0),  (-1,0),  C_NAVY),
        ('TEXTCOLOR',     (0,0),  (-1,0),  C_WHITE),
        ('FONTNAME',      (0,0),  (-1,0),  'Helvetica-Bold'),
        ('FONTSIZE',      (0,0),  (-1,-1), 7.5),
        ('ROWBACKGROUNDS',(0,1),  (-1,-1), [C_WHITE, C_ORANGE_LT]),
        ('BOX',           (0,0),  (-1,-1), 0.5, C_GRAY),
        ('INNERGRID',     (0,0),  (-1,-1), 0.3, HexColor('#E5E7EB')),
        ('TOPPADDING',    (0,0),  (-1,-1), 4),
        ('BOTTOMPADDING', (0,0),  (-1,-1), 4),
        ('LEFTPADDING',   (0,0),  (-1,-1), 6),
        ('VALIGN',        (0,0),  (-1,-1), 'TOP'),
    ]))
    story.append(mn_t)

    doc.build(story)
    print("PDF generated successfully!")

if __name__ == '__main__':
    build()
Running Command

cd /home/daytona/workspace/mbbs-study-pdf && python3 generate_pdf.py 2>&1

Editing File

~/mbbs-study-pdf/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/mbbs-study-pdf/generate_pdf.py'
Running Command

cd /home/daytona/workspace/mbbs-study-pdf && python3 generate_pdf.py 2>&1

Searching Content

"story.append(neph_comp[0:0])" in ~/mbbs-study-pdf

Editing File

~/mbbs-study-pdf/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/mbbs-study-pdf/generate_pdf.py'
Running Command

cd /home/daytona/workspace/mbbs-study-pdf && python3 generate_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/mbbs-study-pdf/MBBS_Case_Study_Summary.pdf

Your PDF is ready! Download it here:

MBBS Case Study Summary

PDF Document · PDF


What's inside the PDF (25+ pages)

The PDF is organized into colour-coded sections with visual flowcharts for every case:
SectionContent
Cover PageFull index/table of contents with all 26 cases
Case 1 - MIFlowchart: Chest pain → CK-MB index → Flipped LDH → Diagnosis. CK isoenzyme table.
Case 2 - PancreatitisFlowchart: Epigastric pain → Amylase/Lipase → Hypocalcemia mechanism
Case 3 - Metabolic SyndromeNCEP-ATP III criteria table, insulin resistance
Case 4 - Von Gierke'sFlowchart: Doll-face infant → G6Pase deficiency → HLLU tetrad
Case 5 - Starvation KetoacidosisStarvation vs DKA comparison flowchart
Case 6 - GoutUric acid pathway, Allopurinol mechanism
Cases 7-9 - Jaundice3-way comparison flowchart + full comparison table (Hemolytic / Hepatic / Obstructive)
Cases 10-11 - RenalNephrotic vs Nephritic side-by-side diagnosis flowchart + comparison table
Case 12 - HyperthyroidismTFT interpretation table, Graves' mechanism
Cases 13-14 - Acid-BaseMaster flowchart: pH → pCO₂/HCO₃ → diagnosis + all 4 disorders table
Case 15 - NAFLDALT vs AST pattern table
Case 16 - Amino AcidopathiesPKU flowchart + comparison table (PKU, Alkaptonuria, Homocystinuria, MSUD, Albinism, Cystinuria)
Case 17 - KwashiorkorKwashiorkor vs Marasmus comparison table
Minor CasesVitamins A/D/C/B1/B3/B12 summary table; IDA flowchart; Tetany/Goitre/Fluorosis; Galactosemia
Tumour MarkersPSA, CA 15-3, HER-2 table
Master MnemonicsAll key mnemonics in one table (PVT TIM HaLL, MUDPILES, HLLU, COLA, 4D's, etc.)

i'm unable to download

Running Command

ls -lh /home/daytona/workspace/mbbs-study-pdf/ && file /home/daytona/workspace/m…

Running Command

# Copy to workspace root for easier access, also try base64 encoding for direct …

Try this direct path link:

MBBS Case Study Summary

PDF Document · PDF


If that still doesn't work, here are a few things to try:
Option 1 - Right-click the link Right-click the link above → "Save link as..." or "Download linked file"
Option 2 - Try a different browser Chrome and Edge tend to handle these sandbox file links better than Firefox or Safari.
Option 3 - Direct path If you're on a system where the workspace is mounted, navigate directly to:
/home/daytona/workspace/MBBS_Case_Study_Summary.pdf
Option 4 - Ask me to convert it I can convert the PDF content into a different format you can use:
  • A Word document (.docx) - easier to download in some setups
  • A ZIP file containing the PDF
  • The full text content pasted directly into chat
Which would you prefer? Just let me know and I'll sort it out right away.
This is a shared conversation. Sign in to Orris to start your own chat.