Tell detail about asi lab technician exam dates dame a mock test for it too

Searching the Web

ASI Lab Technician exam 2026 dates schedule notification

Searching the Web

ASI Lab Technician exam syllabus pattern eligibility 2026

Reading Web Page

https://testbook.com/news/cisf-asi-paramedical-notification-…

Here is a complete guide covering both the CISF ASI (Lab Technician) and BSF ASI (Lab Technician) 2026 recruitments, followed by a full mock test.

ASI Lab Technician Exam 2026 - Complete Guide

1. CISF ASI (Lab Technician) 2026

DetailInfo
Conducting BodyCentral Industrial Security Force (CISF)
Notification Released2nd June 2026
Application Start08 June 2026
Last Date to Apply07 July 2026 (applications are now closed)
Total Vacancies (all paramedical)24 Posts
SalaryRs. 29,200 - Rs. 92,300 (Pay Level-5)
Job LocationAll India

Eligibility (CISF ASI Lab Technician)

  • Age: 18 to 28 years
  • Education: 10+2 (Science stream) + 2-Year Diploma in Medical Lab Technology from a recognized institute
  • Nationality: Indian (male and female both eligible)

Selection Process (CISF)

  1. Written Exam (CBT/OMR based)
  2. Physical Standard Test (PST)
  3. Documentation Verification
  4. Biometric Verification & Aptitude Test (BVAT)
  5. Medical Examination

CISF Written Exam Pattern

  • Mode: CBT or OMR (objective type, English & Hindi)
  • Total Marks: 100
  • Duration: 2 hours
  • Negative Marking: None
  • Questions: Trade/professional knowledge based

2. BSF ASI (Lab Technician) 2026

BSF ASI Lab Technician Exam Pattern

SubjectQuestionsMarksDuration
General Knowledge & Numerical Aptitude2525120 min
Human Anatomy & Physiology2525(combined)
Professional Subjects (Lab Tech specific)5050
Total1001002 hours
  • Mode: Offline (Pen and Paper), MCQ
  • Qualifying Marks: 45% (General/OBC), 35% (SC/ST)
  • No negative marking mentioned

BSF ASI Lab Technician Syllabus

SectionTopics
General KnowledgeCurrent affairs, History, Science, Polity
Human Anatomy & PhysiologyBody systems, Organs, Physiology basics
BiochemistryEnzymes, Metabolic pathways, Clinical chemistry
Microbiology + ImmunologyBacteria, Viruses, Fungi, Antibody-antigen reactions
Hematology & Blood BankingCBC, Blood groups, Coagulation, Transfusion
Histopathology + Molecular BiologyTissue processing, Staining, PCR, FISH
Laboratory ManagementQuality control, Safety, Equipment maintenance
Parasitology, Serology & VirologyParasites, ELISA, VDRL, Viral infections
Note: The CISF written exam date has not yet been officially announced (applications closed July 7, 2026). Keep checking cisfrectt.cisf.gov.in for the exam date and admit card.


MOCK TEST - ASI Lab Technician 2026

100 Questions | 100 Marks | 2 Hours


SECTION A: General Knowledge & Numerical Aptitude (25 Questions)

1. The headquarters of the Central Industrial Security Force (CISF) is located in:
  • A) Mumbai
  • B) New Delhi ✅
  • C) Hyderabad
  • D) Chennai
2. Which Article of the Indian Constitution deals with the Right to Equality?
  • A) Article 12
  • B) Article 19
  • C) Article 14 ✅
  • D) Article 21
3. The normal pH of human blood is approximately:
  • A) 6.8
  • B) 7.0
  • C) 7.4 ✅
  • D) 8.0
4. Who is the current Director General of BSF (as of 2026)?
  • A) Vivek Johri
  • B) Nitin Agrawal ✅
  • C) Rajeev Rai Bhatnagar
  • D) K.K. Sharma
5. India celebrates National Science Day on:
  • A) January 28
  • B) February 28 ✅
  • C) March 15
  • D) April 7
6. If 15% of a number is 90, what is the number?
  • A) 500
  • B) 550
  • C) 600 ✅
  • D) 650
7. A train travels 360 km in 4 hours. What is its speed in m/s?
  • A) 20 m/s
  • B) 25 m/s ✅
  • C) 30 m/s
  • D) 35 m/s
8. Which of the following is NOT a Central Armed Police Force (CAPF)?
  • A) CRPF
  • B) BSF
  • C) CISF
  • D) Assam Rifles ✅
9. The Chandrayaan-3 mission successfully landed on the Moon's south pole in which year?
  • A) 2022
  • B) 2023 ✅
  • C) 2024
  • D) 2025
10. If the ratio of boys to girls in a class is 3:2 and there are 30 boys, how many girls are there?
  • A) 15
  • B) 20 ✅
  • C) 25
  • D) 18
11. Simple interest on Rs. 5000 at 8% per annum for 3 years is:
  • A) Rs. 1000
  • B) Rs. 1200 ✅
  • C) Rs. 1500
  • D) Rs. 2000
12. Which vitamin is known as the "Sunshine Vitamin"?
  • A) Vitamin A
  • B) Vitamin B12
  • C) Vitamin C
  • D) Vitamin D ✅
13. The full form of ELISA is:
  • A) Enzyme-Linked Immunosorbent Assay ✅
  • B) Electrolyte Linked Immune Serum Assay
  • C) Enzymatic Labeling Immuno-Specific Analysis
  • D) Electrophoretic Linked Isotope Serum Assay
14. A tap fills a tank in 6 hours. Another tap empties it in 12 hours. If both are open together, the tank fills in:
  • A) 10 hours
  • B) 12 hours ✅
  • C) 8 hours
  • D) 9 hours
15. Which organization regulates medical laboratories in India?
  • A) ICMR ✅
  • B) MCI
  • C) NABH
  • D) FSSAI
16. The largest organ of the human body is:
  • A) Liver
  • B) Lung
  • C) Skin ✅
  • D) Brain
17. Who wrote "Discovery of India"?
  • A) Mahatma Gandhi
  • B) Jawaharlal Nehru ✅
  • C) B.R. Ambedkar
  • D) Subhash Chandra Bose
18. Average of 5 numbers is 40. If one number is removed, the average becomes 35. The removed number is:
  • A) 55
  • B) 60 ✅
  • C) 65
  • D) 70
19. Which gas is used in sterilization of medical equipment?
  • A) Nitrogen
  • B) Carbon dioxide
  • C) Ethylene oxide ✅
  • D) Oxygen
20. The 2024 Paris Olympics motto was:
  • A) "Faster, Higher, Stronger - Together" ✅
  • B) "United by Emotion"
  • C) "One World One Dream"
  • D) "Come Together"
21. A worker earns Rs. 8000/month. He spends 75% of his income. How much does he save per year?
  • A) Rs. 20,000
  • B) Rs. 24,000 ✅
  • C) Rs. 18,000
  • D) Rs. 30,000
22. The Bharat Biotech COVID-19 vaccine is called:
  • A) Covishield
  • B) Covaxin ✅
  • C) Sputnik V
  • D) ZyCoV-D
23. Which element has the chemical symbol "Fe"?
  • A) Fluorine
  • B) Francium
  • C) Iron ✅
  • D) Fermium
24. If 12 men complete a work in 8 days, how many days will 16 men take?
  • A) 4 days
  • B) 6 days ✅
  • C) 8 days
  • D) 10 days
25. The United Nations was founded in which year?
  • A) 1941
  • B) 1943
  • C) 1945 ✅
  • D) 1947

SECTION B: Human Anatomy & Physiology (25 Questions)

26. The normal adult RBC count (per microlitre) is approximately:
  • A) 2-3 million
  • B) 4-6 million ✅
  • C) 7-9 million
  • D) 1-2 million
27. Which chamber of the heart pumps oxygenated blood to the entire body?
  • A) Right atrium
  • B) Left atrium
  • C) Right ventricle
  • D) Left ventricle ✅
28. The functional unit of the kidney is:
  • A) Alveolus
  • B) Nephron ✅
  • C) Villus
  • D) Acinus
29. Normal adult hemoglobin level in males is:
  • A) 10-12 g/dL
  • B) 12-14 g/dL
  • C) 13-17 g/dL ✅
  • D) 18-20 g/dL
30. Which enzyme initiates the digestion of starch in the mouth?
  • A) Pepsin
  • B) Lipase
  • C) Salivary amylase ✅
  • D) Trypsin
31. The normal blood pressure in adults is:
  • A) 100/70 mmHg
  • B) 120/80 mmHg ✅
  • C) 140/90 mmHg
  • D) 130/85 mmHg
32. Which hormone is secreted by the adrenal medulla?
  • A) Cortisol
  • B) Aldosterone
  • C) Adrenaline (Epinephrine) ✅
  • D) Insulin
33. The blood-brain barrier is primarily formed by:
  • A) Neurons
  • B) Astrocytes ✅
  • C) Microglia
  • D) Oligodendrocytes
34. The site of gas exchange in the lungs is the:
  • A) Bronchi
  • B) Bronchioles
  • C) Alveoli ✅
  • D) Trachea
35. Normal adult white blood cell (WBC) count is:
  • A) 1,000-3,000/µL
  • B) 4,000-11,000/µL ✅
  • C) 12,000-15,000/µL
  • D) 20,000-25,000/µL
36. Which organ produces bile?
  • A) Pancreas
  • B) Gallbladder
  • C) Liver ✅
  • D) Spleen
37. The normal fasting blood glucose level is:
  • A) 40-60 mg/dL
  • B) 70-100 mg/dL ✅
  • C) 120-140 mg/dL
  • D) 150-180 mg/dL
38. The largest bone in the human body is:
  • A) Tibia
  • B) Humerus
  • C) Femur ✅
  • D) Radius
39. Which blood cells are responsible for clotting?
  • A) Erythrocytes
  • B) Leukocytes
  • C) Thrombocytes (Platelets) ✅
  • D) Monocytes
40. Normal urine output in adults per day is approximately:
  • A) 500 mL
  • B) 1000-1500 mL
  • C) 1500-2000 mL ✅
  • D) 3000 mL
41. Which part of the brain controls body temperature?
  • A) Cerebellum
  • B) Medulla oblongata
  • C) Hypothalamus ✅
  • D) Thalamus
42. The normal platelet count in adults is:
  • A) 50,000-100,000/µL
  • B) 150,000-400,000/µL ✅
  • C) 500,000-700,000/µL
  • D) 1,000,000/µL
43. Which type of immunity is provided by breast milk?
  • A) Active artificial
  • B) Active natural
  • C) Passive natural ✅
  • D) Passive artificial
44. The ABO blood grouping is determined by antigens on:
  • A) White blood cells
  • B) Plasma proteins
  • C) Red blood cell surface ✅
  • D) Platelets
45. Heparin is produced by which cells?
  • A) Kupffer cells
  • B) Mast cells ✅
  • C) Plasma cells
  • D) Chief cells
46. Which cranial nerve controls eye movement (most)?
  • A) Optic nerve
  • B) Oculomotor nerve ✅
  • C) Trochlear nerve
  • D) Facial nerve
47. The hormone responsible for "fight or flight" response is:
  • A) Cortisol
  • B) Glucagon
  • C) Adrenaline ✅
  • D) Thyroxine
48. Which plasma protein is most abundant?
  • A) Globulin
  • B) Fibrinogen
  • C) Albumin ✅
  • D) Prothrombin
49. The nephron loop that concentrates urine is called:
  • A) Bowman's capsule
  • B) Loop of Henle ✅
  • C) Distal convoluted tubule
  • D) Collecting duct
50. Normal ESR (Westergren) in adult males is:
  • A) 0-5 mm/hr
  • B) 0-15 mm/hr ✅
  • C) 20-30 mm/hr
  • D) 40-50 mm/hr

SECTION C: Professional Lab Technician Subjects (50 Questions)

Hematology & Blood Banking

51. The "Gold Standard" method for WBC differential count is:
  • A) Automated counter
  • B) Manual peripheral smear ✅
  • C) Flow cytometry
  • D) Bone marrow biopsy
52. EDTA is the preferred anticoagulant for:
  • A) Coagulation tests
  • B) Blood culture
  • C) Complete blood count (CBC) ✅
  • D) Blood glucose
53. In the ABO system, a person with blood group O has:
  • A) Antigen A and B
  • B) Antigen A only
  • C) No ABO antigens ✅
  • D) Antigen B only
54. The Coombs test (Direct) detects:
  • A) Free antibodies in serum
  • B) Antibodies coating RBCs ✅
  • C) Blood group antigens
  • D) Complement proteins in plasma
55. Sickle cell anemia is caused by a mutation in which chain of hemoglobin?
  • A) Alpha chain
  • B) Beta chain ✅
  • C) Delta chain
  • D) Gamma chain
56. The coagulation factor deficient in Hemophilia A is:
  • A) Factor VII
  • B) Factor IX
  • C) Factor VIII ✅
  • D) Factor X
57. Packed Cell Volume (PCV/Hematocrit) normal range in adult males is:
  • A) 25-35%
  • B) 36-46%
  • C) 40-54% ✅
  • D) 55-65%
58. The Rh factor antigen most commonly causing hemolytic disease of the newborn is:
  • A) Rh-c
  • B) Rh-D ✅
  • C) Rh-E
  • D) Rh-C
59. Reticulocyte count is used to assess:
  • A) Platelet function
  • B) Bone marrow erythropoietic activity ✅
  • C) Liver function
  • D) Clotting time
60. Prothrombin Time (PT) measures which pathway?
  • A) Intrinsic pathway
  • B) Common pathway
  • C) Extrinsic pathway ✅
  • D) Fibrinolytic pathway

Microbiology & Immunology

61. Gram-positive bacteria appear which color after Gram staining?
  • A) Red/Pink
  • B) Colorless
  • C) Violet/Purple ✅
  • D) Yellow
62. Which culture media is used for isolation of Mycobacterium tuberculosis?
  • A) Blood agar
  • B) MacConkey agar
  • C) Lowenstein-Jensen (LJ) medium ✅
  • D) Chocolate agar
63. The Mantoux test detects immunity/infection against:
  • A) Typhoid
  • B) Malaria
  • C) Tuberculosis ✅
  • D) Hepatitis B
64. Which stain is used to identify AFB (Acid-Fast Bacilli)?
  • A) Gram stain
  • B) Ziehl-Neelsen stain ✅
  • C) India ink
  • D) Giemsa stain
65. VDRL test is used for diagnosis of:
  • A) HIV
  • B) Syphilis ✅
  • C) Gonorrhea
  • D) Malaria
66. Secretory IgA is the predominant antibody found in:
  • A) Blood serum
  • B) Cerebrospinal fluid
  • C) Body secretions (saliva, breast milk, tears) ✅
  • D) Lymph nodes
67. The first line of defense in innate immunity includes:
  • A) B lymphocytes
  • B) T lymphocytes
  • C) Skin and mucous membranes ✅
  • D) Antibodies
68. India ink preparation is used to identify:
  • A) Aspergillus
  • B) Candida
  • C) Cryptococcus neoformans ✅
  • D) Histoplasma
69. Which hepatitis virus is transmitted by feco-oral route?
  • A) Hepatitis B
  • B) Hepatitis C
  • C) Hepatitis D
  • D) Hepatitis A ✅
70. The autoclave sterilizes at which temperature?
  • A) 100°C at 15 psi
  • B) 121°C at 15 psi ✅
  • C) 160°C at 15 psi
  • D) 180°C at atmospheric pressure

Biochemistry & Clinical Chemistry

71. The reference method for blood glucose estimation is:
  • A) Benedict's test
  • B) Glucose oxidase method ✅
  • C) Fehling's test
  • D) Folin-Wu method
72. Which enzyme is a marker for myocardial infarction (heart attack)?
  • A) ALT
  • B) AST
  • C) Troponin I/T ✅
  • D) Amylase
73. Normal serum creatinine in adult males is:
  • A) 0.2-0.4 mg/dL
  • B) 0.7-1.2 mg/dL ✅
  • C) 2.0-3.5 mg/dL
  • D) 4.0-5.0 mg/dL
74. HbA1c reflects blood glucose control over the past:
  • A) 2 weeks
  • B) 4 weeks
  • C) 2-3 months ✅
  • D) 6 months
75. Which test is used to assess kidney filtration function?
  • A) Serum bilirubin
  • B) Serum albumin
  • C) Glomerular Filtration Rate (GFR) ✅
  • D) Serum lipase
76. Lipase is elevated in disease of which organ?
  • A) Liver
  • B) Kidney
  • C) Pancreas ✅
  • D) Heart
77. The normal total bilirubin level in blood is:
  • A) 0.1-0.5 mg/dL
  • B) 0.2-1.2 mg/dL ✅
  • C) 2.0-3.5 mg/dL
  • D) 5.0-7.0 mg/dL
78. Which lipoprotein is known as "bad cholesterol"?
  • A) HDL
  • B) VLDL
  • C) LDL ✅
  • D) Chylomicron
79. The Beer-Lambert law is the principle behind:
  • A) Centrifugation
  • B) Colorimetry/Spectrophotometry ✅
  • C) Electrophoresis
  • D) Chromatography
80. Phenylketonuria (PKU) is a disorder of metabolism of which amino acid?
  • A) Tyrosine
  • B) Tryptophan
  • C) Phenylalanine ✅
  • D) Leucine

Histopathology & Molecular Biology

81. The most common stain used in routine histopathology is:
  • A) PAS stain
  • B) Masson's trichrome
  • C) Hematoxylin and Eosin (H&E) ✅
  • D) Giemsa stain
82. Formalin (10% neutral buffered) is used for:
  • A) Freezing tissue
  • B) Fixation of tissues ✅
  • C) Staining
  • D) Decalcification
83. PCR (Polymerase Chain Reaction) is used to:
  • A) Separate proteins
  • B) Amplify specific DNA sequences ✅
  • C) Stain chromosomes
  • D) Culture bacteria
84. The processing step that removes water from tissue before embedding is:
  • A) Fixation
  • B) Clearing
  • C) Dehydration ✅
  • D) Infiltration
85. FISH (Fluorescence In Situ Hybridization) is used to detect:
  • A) Protein expression
  • B) Chromosomal abnormalities/gene amplification ✅
  • C) Blood group antigens
  • D) Enzyme activity

Parasitology & Serology

86. Malaria is caused by which parasite?
  • A) Leishmania
  • B) Trypanosoma
  • C) Plasmodium ✅
  • D) Toxoplasma
87. The Rapid Malarial Antigen (RMA) test detects:
  • A) Antibodies against malaria
  • B) Plasmodium antigens (HRP-2, pLDH) ✅
  • C) Malarial DNA
  • D) RBC morphology changes
88. Widal test is used for the diagnosis of:
  • A) Malaria
  • B) Typhoid fever ✅
  • C) Dengue
  • D) Leptospirosis
89. The Dengue NS1 antigen test is most useful in:
  • A) 2nd week of fever
  • B) 3rd week of fever
  • C) First 5 days of fever ✅
  • D) Convalescent phase
90. Ascaris lumbricoides is transmitted through:
  • A) Mosquito bite
  • B) Contaminated food and water ✅
  • C) Direct skin contact
  • D) Airborne route

Lab Quality & Safety

91. QC material used in a laboratory to check assay performance is called:
  • A) Standard
  • B) Blank
  • C) Control ✅
  • D) Reagent
92. Levey-Jennings chart is used to monitor:
  • A) Patient results
  • B) Reagent expiry
  • C) Laboratory quality control ✅
  • D) Equipment calibration schedule
93. Which symbol on a reagent bottle indicates biohazard?
  • A) Skull and crossbones
  • B) Three-pointed trefoil/circle symbol ✅
  • C) Flame symbol
  • D) Corrosion symbol
94. Standard precautions in the lab require wearing gloves when:
  • A) Only when handling blood
  • B) When handling all patient specimens ✅
  • C) Only during centrifugation
  • D) Only when a patient has a known infection
95. The "chain of custody" in laboratory specimens is important for:
  • A) Billing purposes
  • B) Specimen integrity and legal purposes ✅
  • C) Faster processing
  • D) Cost reduction
96. The term "hemolysis" in a specimen refers to:
  • A) Clotting of blood
  • B) Destruction of red blood cells ✅
  • C) Bacterial contamination
  • D) Lipemia
97. Which tube (color code) contains EDTA as anticoagulant?
  • A) Red/Gold (SST)
  • B) Light blue (citrate)
  • C) Purple/Lavender ✅
  • D) Green (heparin)
98. Autoclave spore testing uses:
  • A) E. coli
  • B) Bacillus stearothermophilus ✅
  • C) Staphylococcus aureus
  • D) Clostridium perfringens
99. NABL stands for:
  • A) National Accreditation Board for Laboratories
  • B) National Accreditation Board for Testing and Calibration Laboratories ✅
  • C) National Association of Bio-Labs
  • D) National Authority for Biomedical Laboratories
100. Which type of pipette is most accurate for measuring small volumes?
  • A) Pasteur pipette
  • B) Graduated (Mohr) pipette
  • C) Micropipette (calibrated) ✅
  • D) Wash bottle

Answer Key Summary

QAnsQAnsQAnsQAns
1B26B51B76C
2C27D52C77B
3C28B53C78C
4B29C54B79B
5B30C55B80C
6C31B56C81C
7B32C57C82B
8D33B58B83B
9B34C59B84C
10B35B60C85B
11B36C61C86C
12D37B62C87B
13A38C63C88B
14B39C64B89C
15A40C65B90B
16C41C66C91C
17B42B67C92C
18B43C68C93B
19C44C69D94B
20A45B70B95B
21B46B71B96B
22B47C72C97C
23C48C73B98B
24B49B74C99B
25C50B75C100C

Key Takeaways & Prep Tips

  • Exam date for CISF ASI Lab Technician 2026 has NOT been officially announced yet. Applications closed July 7, 2026. Watch cisfrectt.cisf.gov.in for admit card and exam date updates.
  • BSF ASI Lab Technician notification details are typically released separately. Check rectt.bsf.gov.in.
  • Focus heavily on Hematology, Microbiology, and Biochemistry - these form the bulk of the professional section.
  • Practice numerical aptitude daily (ratio, percentage, time-work, SI/CI).
  • There is no negative marking in either exam, so attempt all questions.
  • Aim for at least 70+ out of 100 to be safely competitive.

Create a comprehensive study guide PDF for ASI Lab Technician

Reading File
Reading File
Running Command

ls -la /tmp/workspace/ 2>/dev/null || mkdir -p /tmp/workspace && ls -la /tmp/workspace/

Running Command

mkdir -p /tmp/workspace/asi-lab-tech-guide

Writing File

~/asi-lab-tech-guide/build_guide.py


from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    PageBreak, HRFlowable, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.lib.colors import HexColor
import os

OUTPUT = "/tmp/workspace/asi-lab-tech-guide/ASI_Lab_Technician_Study_Guide_2026.pdf"

# ── Color palette ──────────────────────────────────────────────
DARK_BLUE   = HexColor("#1A237E")
MID_BLUE    = HexColor("#283593")
ACCENT_BLUE = HexColor("#1976D2")
LIGHT_BLUE  = HexColor("#E3F2FD")
TEAL        = HexColor("#00897B")
TEAL_LIGHT  = HexColor("#E0F2F1")
RED         = HexColor("#C62828")
RED_LIGHT   = HexColor("#FFEBEE")
AMBER       = HexColor("#F57F17")
AMBER_LIGHT = HexColor("#FFFDE7")
GREEN       = HexColor("#2E7D32")
GREEN_LIGHT = HexColor("#E8F5E9")
GREY_DARK   = HexColor("#37474F")
GREY_MID    = HexColor("#546E7A")
GREY_LIGHT  = HexColor("#ECEFF1")
WHITE       = colors.white
BLACK       = colors.black

W, H = A4
MARGIN = 2*cm

# ── Styles ─────────────────────────────────────────────────────
styles = getSampleStyleSheet()

def S(name, **kw):
    return ParagraphStyle(name, **kw)

cover_title = S("CoverTitle",
    fontName="Helvetica-Bold", fontSize=30, textColor=WHITE,
    alignment=TA_CENTER, leading=38, spaceAfter=10)

cover_sub = S("CoverSub",
    fontName="Helvetica", fontSize=15, textColor=HexColor("#BBDEFB"),
    alignment=TA_CENTER, leading=22, spaceAfter=6)

cover_info = S("CoverInfo",
    fontName="Helvetica-Bold", fontSize=12, textColor=HexColor("#FFD54F"),
    alignment=TA_CENTER, spaceAfter=4)

ch_title = S("ChTitle",
    fontName="Helvetica-Bold", fontSize=18, textColor=WHITE,
    alignment=TA_LEFT, leading=24, spaceBefore=0, spaceAfter=0)

sec_head = S("SecHead",
    fontName="Helvetica-Bold", fontSize=13, textColor=DARK_BLUE,
    spaceBefore=14, spaceAfter=6, leading=17)

sub_head = S("SubHead",
    fontName="Helvetica-Bold", fontSize=11, textColor=MID_BLUE,
    spaceBefore=10, spaceAfter=4, leading=15)

body = S("Body",
    fontName="Helvetica", fontSize=9.5, textColor=GREY_DARK,
    leading=14, spaceAfter=4, alignment=TA_JUSTIFY)

bullet_style = S("Bullet",
    fontName="Helvetica", fontSize=9.5, textColor=GREY_DARK,
    leading=13, spaceAfter=3, leftIndent=14, bulletIndent=0,
    bulletFontName="Helvetica", bulletFontSize=9.5)

note_style = S("Note",
    fontName="Helvetica-Oblique", fontSize=9, textColor=HexColor("#4527A0"),
    leading=13, spaceAfter=4, leftIndent=10)

key_style = S("Key",
    fontName="Helvetica-Bold", fontSize=9.5, textColor=GREEN,
    leading=13, spaceAfter=3, leftIndent=14)

toc_item = S("TOCItem",
    fontName="Helvetica", fontSize=10, textColor=GREY_DARK,
    leading=18, leftIndent=20)

toc_ch = S("TOCCh",
    fontName="Helvetica-Bold", fontSize=11, textColor=DARK_BLUE,
    leading=20, spaceBefore=4)

warn_style = S("Warn",
    fontName="Helvetica-Bold", fontSize=9.5, textColor=RED,
    leading=13, spaceAfter=3, leftIndent=10)

# ── Helper Flowables ───────────────────────────────────────────

class ColorRect(Flowable):
    """Full-width colored banner for chapter headers."""
    def __init__(self, color, height=1.1*cm, radius=6):
        Flowable.__init__(self)
        self.color = color
        self.bh = height
        self.radius = radius

    def draw(self):
        self.canv.setFillColor(self.color)
        self.canv.roundRect(0, 0, self.width, self.bh, self.radius, fill=1, stroke=0)

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


class ChapterHeader(Flowable):
    """Draws colored banner + chapter text inline."""
    def __init__(self, number, title, color=DARK_BLUE, height=1.2*cm):
        Flowable.__init__(self)
        self.number = number
        self.title = title
        self.color = color
        self.bh = height

    def draw(self):
        c = self.canv
        c.setFillColor(self.color)
        c.roundRect(0, 0, self.width, self.bh, 8, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont("Helvetica-Bold", 15)
        c.drawString(14, self.bh * 0.28, f"Chapter {self.number}: {self.title}")

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


def colored_box(paragraphs, bg=LIGHT_BLUE, border=ACCENT_BLUE, radius=6):
    data = [[p] for p in paragraphs]
    t = Table(data, colWidths=[W - 2*MARGIN])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("ROUNDEDCORNERS", [radius]),
        ("BOX", (0,0), (-1,-1), 1.2, border),
        ("TOPPADDING", (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING", (0,0), (-1,-1), 12),
        ("RIGHTPADDING", (0,0), (-1,-1), 12),
    ]))
    return t


def info_table(rows, col_widths=None, header_bg=DARK_BLUE, alt_bg=LIGHT_BLUE):
    if col_widths is None:
        n = len(rows[0])
        col_widths = [(W - 2*MARGIN)/n] * n
    t = Table(rows, colWidths=col_widths)
    style = [
        ("BACKGROUND", (0,0), (-1,0), header_bg),
        ("TEXTCOLOR", (0,0), (-1,0), WHITE),
        ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE", (0,0), (-1,0), 9),
        ("ALIGN", (0,0), (-1,-1), "CENTER"),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("FONTNAME", (0,1), (-1,-1), "Helvetica"),
        ("FONTSIZE", (0,1), (-1,-1), 8.5),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, alt_bg]),
        ("GRID", (0,0), (-1,-1), 0.5, HexColor("#B0BEC5")),
        ("TOPPADDING", (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING", (0,0), (-1,-1), 6),
        ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ]
    t.setStyle(TableStyle(style))
    return t


def bullet(text, style=bullet_style):
    return Paragraph(f"•  {text}", style)


def kv(key, val):
    return Paragraph(f"<b>{key}:</b> {val}", body)


def sp(n=6):
    return Spacer(1, n)


# ── Cover Page ─────────────────────────────────────────────────

def cover_page():
    elems = []

    # Big dark blue background rectangle simulated by a full-page table
    cover_data = [[""]]
    ct = Table(cover_data, colWidths=[W - 2*MARGIN], rowHeights=[3.5*cm])
    ct.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
        ("BOX", (0,0), (-1,-1), 0, DARK_BLUE),
        ("TOPPADDING", (0,0), (-1,-1), 0),
        ("BOTTOMPADDING", (0,0), (-1,-1), 0),
    ]))
    elems.append(sp(20))

    # Top banner
    banner_items = [
        Paragraph("CISF / BSF", cover_info),
        Paragraph("ASI (Lab Technician)", cover_title),
        Paragraph("Comprehensive Study Guide 2026", cover_sub),
        sp(4),
        Paragraph("Written Exam · Physical Test · Selection Process", cover_info),
        sp(4),
        Paragraph("100 Marks · 2 Hours · Objective Type (MCQ)", cover_sub),
    ]
    banner = Table([[p] for p in banner_items], colWidths=[W - 2*MARGIN])
    banner.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
        ("TOPPADDING", (0,0), (-1,-1), 6),
        ("BOTTOMPADDING", (0,0), (-1,-1), 6),
        ("LEFTPADDING", (0,0), (-1,-1), 20),
        ("RIGHTPADDING", (0,0), (-1,-1), 20),
    ]))
    elems.append(banner)
    elems.append(sp(16))

    # Highlights strip
    hi_data = [["Subject", "Questions", "Marks", "Duration"],
               ["General Knowledge & Aptitude", "25", "25", ""],
               ["Human Anatomy & Physiology", "25", "25", "2 Hours"],
               ["Professional Subjects (Lab Tech)", "50", "50", ""],
               ["TOTAL", "100", "100", "120 min"]]
    elems.append(info_table(hi_data, col_widths=[8.5*cm, 3.5*cm, 3*cm, 3*cm]))
    elems.append(sp(16))

    # Feature boxes row
    feat = [
        ("Eligibility", "10+2 Science +\n2-Yr MLT Diploma"),
        ("Salary", "Rs. 29,200–92,300\nPay Level-5"),
        ("Vacancies", "CISF: 24 Posts\nBSF: As notified"),
        ("Selection", "Written → PST\n→ Medical"),
    ]
    feat_cells = [[Paragraph(f"<b><font color='#{DARK_BLUE.hexval()[2:]}' size='9'>{t}</font></b><br/>"
                              f"<font size='8.5' color='#546E7A'>{v}</font>", body)] for t,v in feat]
    feat_table = Table([feat_cells], colWidths=[(W - 2*MARGIN)/4]*4)
    feat_table.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), LIGHT_BLUE),
        ("BOX", (0,0), (-1,-1), 1, ACCENT_BLUE),
        ("LINEAFTER", (0,0), (-2,-1), 0.5, ACCENT_BLUE),
        ("ALIGN", (0,0), (-1,-1), "CENTER"),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("TOPPADDING", (0,0), (-1,-1), 10),
        ("BOTTOMPADDING", (0,0), (-1,-1), 10),
    ]))
    elems.append(feat_table)
    elems.append(sp(14))

    # Chapters list
    elems.append(Paragraph("What's Inside", S("T", fontName="Helvetica-Bold", fontSize=12,
                            textColor=DARK_BLUE, alignment=TA_CENTER, spaceAfter=6)))
    chapters = [
        "Chapter 1: Exam Overview, Dates & Selection Process",
        "Chapter 2: General Knowledge & Numerical Aptitude",
        "Chapter 3: Human Anatomy & Physiology",
        "Chapter 4: Hematology & Blood Banking",
        "Chapter 5: Microbiology, Immunology & Parasitology",
        "Chapter 6: Biochemistry & Clinical Chemistry",
        "Chapter 7: Histopathology & Molecular Biology",
        "Chapter 8: Laboratory Management, QC & Safety",
        "Chapter 9: Full Mock Test (100 Questions + Answers)",
        "Chapter 10: Quick Revision Tables & Reference Values",
    ]
    for ch in chapters:
        elems.append(Paragraph(f"&#x2714;  {ch}", toc_item))

    elems.append(sp(20))
    elems.append(Paragraph("Prepared for: ASI Paramedical Exam 2026", S("Footer",
        fontName="Helvetica-Oblique", fontSize=9, textColor=GREY_MID, alignment=TA_CENTER)))
    elems.append(PageBreak())
    return elems


# ── Chapter 1: Exam Overview ───────────────────────────────────

def chapter1():
    e = []
    e.append(ChapterHeader("1", "Exam Overview, Dates & Selection Process", DARK_BLUE))
    e.append(sp(10))

    e.append(Paragraph("1.1 CISF ASI (Lab Technician) 2026 Key Dates", sec_head))
    dates = [["Event", "Date / Status"],
             ["Notification Released", "2 June 2026"],
             ["Application Start Date", "8 June 2026"],
             ["Last Date to Apply", "7 July 2026 (CLOSED)"],
             ["Exam Date (Written)", "To be announced - check cisfrectt.cisf.gov.in"],
             ["Admit Card Release", "~10 days before exam"],
             ["Result Declaration", "After exam (official website)"],
             ["Salary (Pay Level-5)", "Rs. 29,200 – Rs. 92,300 per month"]]
    e.append(info_table(dates, col_widths=[8*cm, 9.5*cm]))
    e.append(sp(10))

    e.append(Paragraph("1.2 Eligibility Criteria", sec_head))
    elig = [["Criterion", "CISF ASI Lab Technician", "BSF ASI Lab Technician"],
            ["Age", "18–28 years", "18–25 years (relaxation applicable)"],
            ["Education (Min)", "10+2 (Science stream)", "10+2 (Science stream)"],
            ["Diploma", "2-Year MLT Diploma (recognized institute)", "2-Year MLT Diploma"],
            ["Nationality", "Indian (Male & Female)", "Indian (Male & Female)"],
            ["Physical Fitness", "PST required", "PST required"]]
    e.append(info_table(elig, col_widths=[4*cm, 6.75*cm, 6.75*cm]))
    e.append(sp(6))
    e.append(colored_box([
        Paragraph("<b>Age Relaxation:</b> OBC – 3 years | SC/ST – 5 years | Ex-Servicemen – As per rules | "
                  "PwD – 10 years (UR), 13 years (OBC), 15 years (SC/ST)", note_style)
    ], bg=AMBER_LIGHT, border=AMBER))
    e.append(sp(10))

    e.append(Paragraph("1.3 Selection Process (CISF)", sec_head))
    steps = [
        ("Step 1", "Written Exam (CBT/OMR)", "100 marks, 2 hours, Objective MCQ, No negative marking"),
        ("Step 2", "Physical Standard Test (PST)", "Height, Weight, Chest measurement as per norms"),
        ("Step 3", "Documentation Verification", "Original certificates, Diploma, ID proof"),
        ("Step 4", "BVAT", "Biometric Verification & Aptitude Test"),
        ("Step 5", "Medical Examination", "Vision, hearing, physical fitness standards"),
    ]
    step_data = [["Step", "Stage", "Details"]] + list(steps)
    e.append(info_table(step_data, col_widths=[2.5*cm, 5.5*cm, 9.5*cm], header_bg=TEAL))
    e.append(sp(10))

    e.append(Paragraph("1.4 Exam Pattern (Written Test)", sec_head))
    pattern = [["Section", "Questions", "Marks", "Qualifying Marks"],
               ["General Knowledge & Numerical Aptitude", "25", "25", "45% (Gen/OBC)"],
               ["Human Anatomy & Physiology", "25", "25", "35% (SC/ST)"],
               ["Professional Subjects (Lab Technician)", "50", "50", "—"],
               ["TOTAL", "100", "100", "2 Hours"]]
    e.append(info_table(pattern, col_widths=[7.5*cm, 3*cm, 2.5*cm, 4.5*cm]))
    e.append(sp(8))
    e.append(colored_box([
        Paragraph("<b>Important:</b> There is NO negative marking in either CISF or BSF ASI Lab Technician exam. "
                  "Attempt ALL 100 questions. Mode: Offline (Pen & Paper / OMR sheet).", warn_style)
    ], bg=RED_LIGHT, border=RED))
    e.append(sp(10))

    e.append(Paragraph("1.5 Physical Standard Test (PST) Norms", sec_head))
    pst = [["Category", "Height (Male)", "Height (Female)", "Chest (Male)"],
           ["General / OBC / SC", "170 cm", "157 cm", "80–85 cm"],
           ["ST / Hill Areas", "162.5 cm", "150 cm", "76–81 cm"],
           ["Ex-Servicemen", "As per category", "—", "—"]]
    e.append(info_table(pst, col_widths=[5.5*cm, 3.5*cm, 3.5*cm, 5*cm], header_bg=TEAL))
    e.append(PageBreak())
    return e


# ── Chapter 2: GK & Aptitude ───────────────────────────────────

def chapter2():
    e = []
    e.append(ChapterHeader("2", "General Knowledge & Numerical Aptitude (25 Marks)", ACCENT_BLUE))
    e.append(sp(10))

    e.append(Paragraph("2.1 Important GK Topics", sec_head))
    gk_topics = [
        ("National Organisations", "ICMR, NABH, NABL, FSSAI, MCI/NMC, WHO, Red Cross"),
        ("Important Days", "World Blood Donor Day – 14 June | World Lab Day – 25 Apr | World Health Day – 7 Apr"),
        ("Science Facts", "Normal blood pH: 7.35–7.45 | Body temp: 37°C | Pulse: 60–100/min"),
        ("Indian Polity", "Article 14 (Equality), Article 21 (Life & Liberty), Right to Health"),
        ("Awards", "Nobel Prize in Medicine/Physiology – key discoveries"),
        ("Current Affairs", "COVID-19 vaccines, NABL accreditation, WHO ICD-11"),
        ("Defence Forces", "CISF – HQ New Delhi | BSF – HQ New Delhi | CRPF – HQ New Delhi"),
    ]
    gk_data = [["Topic", "Key Points"]] + [[t, v] for t, v in gk_topics]
    e.append(info_table(gk_data, col_widths=[5.5*cm, 12*cm], header_bg=ACCENT_BLUE))
    e.append(sp(10))

    e.append(Paragraph("2.2 Numerical Aptitude – Key Formulas", sec_head))
    formulas = [
        ("Simple Interest", "SI = (P × R × T) / 100"),
        ("Compound Interest", "CI = P[(1 + R/100)^T – 1]"),
        ("Percentage", "% = (Part/Total) × 100"),
        ("Ratio & Proportion", "If a:b = c:d, then ad = bc"),
        ("Time & Work", "Work = Rate × Time; Combined rate = 1/a + 1/b"),
        ("Speed, Distance, Time", "D = S × T; 1 km/h = 5/18 m/s"),
        ("Average", "Average = Sum of values / Number of values"),
        ("Profit & Loss", "Profit% = (Profit/CP) × 100"),
    ]
    for name, formula in formulas:
        e.append(colored_box([
            Paragraph(f"<b>{name}:</b>  <font color='#C62828'>{formula}</font>", body)
        ], bg=GREEN_LIGHT, border=GREEN))
        e.append(sp(3))
    e.append(sp(6))

    e.append(Paragraph("2.3 Practice Problems", sec_head))
    probs = [
        ("Q1", "15% of 600 = ?", "Answer: 90"),
        ("Q2", "A train of 360 km in 4 hours – speed in m/s?", "Answer: 25 m/s"),
        ("Q3", "SI on Rs. 5000 @ 8% for 3 years?", "Answer: Rs. 1200"),
        ("Q4", "12 men finish in 8 days; 16 men finish in ?", "Answer: 6 days"),
        ("Q5", "Ratio 3:2, boys = 30; girls = ?", "Answer: 20"),
    ]
    prob_data = [["#", "Problem", "Answer"]] + [[q, p, a] for q, p, a in probs]
    e.append(info_table(prob_data, col_widths=[1.5*cm, 11*cm, 5*cm], header_bg=TEAL))
    e.append(PageBreak())
    return e


# ── Chapter 3: Anatomy & Physiology ───────────────────────────

def chapter3():
    e = []
    e.append(ChapterHeader("3", "Human Anatomy & Physiology (25 Marks)", MID_BLUE))
    e.append(sp(10))

    e.append(Paragraph("3.1 Normal Reference Values (Memorise These!)", sec_head))
    e.append(colored_box([
        Paragraph("<b>These values are repeatedly tested in exams. Memorise them all.</b>", warn_style)
    ], bg=AMBER_LIGHT, border=AMBER))
    e.append(sp(6))
    ref = [["Parameter", "Normal Range", "Clinical Note"],
           ["RBC Count (Male)", "4.5–5.5 million/µL", "Low = Anaemia"],
           ["RBC Count (Female)", "3.8–5.0 million/µL", "—"],
           ["Hemoglobin (Male)", "13–17 g/dL", "Low = Anaemia; High = Polycythaemia"],
           ["Hemoglobin (Female)", "12–15 g/dL", "—"],
           ["WBC Count", "4,000–11,000/µL", "High = Infection/Leukaemia"],
           ["Platelet Count", "1.5–4.0 lakh/µL", "Low = Thrombocytopenia"],
           ["PCV/Hematocrit (M)", "40–54%", "—"],
           ["PCV/Hematocrit (F)", "36–46%", "—"],
           ["Blood pH", "7.35–7.45", "Acidosis <7.35; Alkalosis >7.45"],
           ["Fasting Blood Glucose", "70–100 mg/dL", "Diabetes >126 mg/dL"],
           ["Serum Creatinine (M)", "0.7–1.2 mg/dL", "Elevated in Renal failure"],
           ["Total Bilirubin", "0.2–1.2 mg/dL", "High = Jaundice"],
           ["ESR (Male, Westergren)", "0–15 mm/hr", "High in inflammation/infection"],
           ["ESR (Female)", "0–20 mm/hr", "—"],
           ["Blood Pressure (Adult)", "120/80 mmHg", "HTN >140/90"],
           ["Pulse Rate", "60–100/min", "Brady <60; Tachy >100"],
           ["Body Temperature", "37°C (98.6°F)", "Fever >38°C"],
           ["Urine Output/Day", "1500–2000 mL", "Oliguria <400 mL"],
           ["Serum Albumin", "3.5–5.0 g/dL", "Low = Malnutrition/Liver disease"],
           ]
    e.append(info_table(ref, col_widths=[6*cm, 4.5*cm, 7*cm], header_bg=DARK_BLUE))
    e.append(sp(10))

    e.append(Paragraph("3.2 Body Systems – Key Points", sec_head))
    systems = [
        ("Cardiovascular", "Heart has 4 chambers. Left ventricle pumps oxygenated blood systemically. "
                           "Right ventricle pumps deoxygenated blood to lungs. SA node = pacemaker."),
        ("Respiratory", "Alveoli = site of gas exchange. Surfactant prevents alveolar collapse. "
                        "Normal respiratory rate: 12–20 breaths/min."),
        ("Renal", "Nephron = functional unit. Loop of Henle concentrates urine. "
                  "GFR = index of kidney function (normal ~125 mL/min)."),
        ("Digestive", "Salivary amylase starts starch digestion. Pepsin digests proteins in stomach. "
                      "Bile emulsifies fats. Liver produces bile; gallbladder stores it."),
        ("Endocrine", "Insulin (beta cells, pancreas) lowers blood glucose. Glucagon raises it. "
                      "Thyroid hormone controls metabolism. Cortisol = stress hormone (adrenal cortex). "
                      "Adrenaline = fight-or-flight (adrenal medulla)."),
        ("Nervous", "CNS = Brain + Spinal cord. Hypothalamus regulates temperature, hunger, thirst. "
                    "Cerebellum controls coordination. Medulla = vital centres (breathing, HR)."),
        ("Musculoskeletal", "206 bones in adults. Femur = longest bone. Calcium + Vit D for bone health. "
                            "Haematopoiesis occurs in red bone marrow."),
    ]
    for system, text in systems:
        e.append(Paragraph(system, sub_head))
        e.append(Paragraph(text, body))
    e.append(PageBreak())
    return e


# ── Chapter 4: Hematology ─────────────────────────────────────

def chapter4():
    e = []
    e.append(ChapterHeader("4", "Hematology & Blood Banking (Core Professional)", TEAL))
    e.append(sp(10))

    e.append(Paragraph("4.1 Anticoagulants Used in Laboratory", sec_head))
    anti = [["Tube Color", "Anticoagulant", "Tests Performed"],
            ["Purple / Lavender", "EDTA (K2 or K3)", "CBC, Blood film, HbA1c, ESR"],
            ["Light Blue", "Sodium Citrate (3.2%)", "PT, aPTT, Coagulation tests"],
            ["Green", "Heparin (Li or Na)", "Plasma chemistry, LFT, RFT"],
            ["Red / Gold (SST)", "None (Clot activator + gel)", "Serology, Biochemistry"],
            ["Grey", "Sodium Fluoride + EDTA", "Glucose, Lactate (inhibits glycolysis)"],
            ["Black", "Sodium Citrate (3.8%)", "ESR (Westergren method)"]]
    e.append(info_table(anti, col_widths=[4*cm, 5.5*cm, 8*cm], header_bg=TEAL))
    e.append(sp(10))

    e.append(Paragraph("4.2 ABO Blood Group System", sec_head))
    abo = [["Blood Group", "Antigens on RBC", "Antibodies in Plasma", "Can Donate To", "Can Receive From"],
           ["A", "A", "Anti-B", "A, AB", "A, O"],
           ["B", "B", "Anti-A", "B, AB", "B, O"],
           ["AB (Universal Recipient)", "A and B", "None", "AB only", "A, B, AB, O"],
           ["O (Universal Donor)", "None", "Anti-A and Anti-B", "A, B, AB, O", "O only"]]
    e.append(info_table(abo, col_widths=[4.5*cm, 3*cm, 3.5*cm, 3*cm, 3.5*cm], header_bg=DARK_BLUE))
    e.append(sp(10))

    e.append(Paragraph("4.3 Key Coagulation Tests", sec_head))
    coag = [["Test", "Normal Range", "Pathway Tested", "Clinical Use"],
            ["Prothrombin Time (PT)", "11–14 seconds", "Extrinsic pathway", "Warfarin monitoring, Liver disease"],
            ["aPTT", "25–35 seconds", "Intrinsic pathway", "Heparin monitoring, Haemophilia"],
            ["INR", "0.8–1.2 (therapeutic 2–3)", "Extrinsic (standardised PT)", "Anticoagulant therapy"],
            ["Fibrinogen", "200–400 mg/dL", "Final common pathway", "DIC, Liver disease"],
            ["Bleeding Time (BT)", "2–7 minutes", "Primary haemostasis", "Platelet function"],
            ["Clotting Time (CT)", "5–10 minutes", "Whole blood clotting", "Gross coagulation defect"]]
    e.append(info_table(coag, col_widths=[4*cm, 3.5*cm, 4*cm, 6*cm], header_bg=TEAL))
    e.append(sp(10))

    e.append(Paragraph("4.4 Haemoglobin Disorders", sec_head))
    hb_dis = [
        ("Sickle Cell Anaemia", "Mutation in beta-globin chain (Glu→Val at position 6). HbS. "
                                "RBCs sickle under low O2. Sickling test + Hb electrophoresis."),
        ("Thalassaemia", "Reduced synthesis of alpha or beta chains. Beta-thal major = severe; "
                         "trait = mild microcytic anaemia. HPLC or electrophoresis to diagnose."),
        ("Iron Deficiency Anaemia", "Most common anaemia. Low serum iron, high TIBC, low ferritin. "
                                    "Microcytic hypochromic RBCs. Treat with oral iron (FeSO4)."),
        ("Megaloblastic Anaemia", "Deficiency of Vit B12 or folate. Macro-ovalocytes, hypersegmented neutrophils. "
                                  "MCV > 100 fL (macrocytosis)."),
    ]
    for name, desc in hb_dis:
        e.append(Paragraph(name, sub_head))
        e.append(Paragraph(desc, body))
    e.append(PageBreak())
    return e


# ── Chapter 5: Microbiology ───────────────────────────────────

def chapter5():
    e = []
    e.append(ChapterHeader("5", "Microbiology, Immunology & Parasitology", HexColor("#6A1B9A")))
    e.append(sp(10))

    e.append(Paragraph("5.1 Staining Techniques", sec_head))
    stains = [["Stain", "Organisms Identified", "Result / Color"],
              ["Gram Stain", "Most bacteria (differential)", "GP = Violet; GN = Pink/Red"],
              ["Ziehl-Neelsen (ZN)", "AFB (M. tuberculosis, M. leprae)", "AFB = Red; Background = Blue"],
              ["India Ink", "Cryptococcus neoformans", "Clear capsule on dark background"],
              ["Giemsa Stain", "Malaria (Plasmodium), blood parasites", "Parasites stained purple"],
              ["PAS Stain", "Fungi, glycogen, mucin", "Positive = Magenta/Pink"],
              ["Acridine Orange", "Bacteria, parasites (fluorescence)", "Bright orange fluorescence"],
              ["Albert's Stain", "Corynebacterium diphtheriae (metachromatic granules)", "Granules = Blue-black"]]
    e.append(info_table(stains, col_widths=[4.5*cm, 6*cm, 7*cm], header_bg=HexColor("#6A1B9A")))
    e.append(sp(10))

    e.append(Paragraph("5.2 Culture Media (Important!)", sec_head))
    media = [["Medium", "Type", "Organisms Grown"],
             ["Blood Agar", "Enriched", "Streptococcus, Staphylococcus (haemolysis patterns)"],
             ["Chocolate Agar", "Enriched (heated blood)", "Neisseria, Haemophilus"],
             ["MacConkey Agar", "Selective + Differential", "Gram-negatives; Lactose fermenters (pink)"],
             ["Lowenstein-Jensen (LJ)", "Selective", "Mycobacterium tuberculosis"],
             ["TCBS Agar", "Selective", "Vibrio cholerae (yellow colonies)"],
             ["Thiosulphate Citrate Bile Sucrose", "Selective", "Vibrio sp."],
             ["Sabouraud Dextrose Agar (SDA)", "Selective", "Fungi, Candida, Dermatophytes"],
             ["CLED Agar", "Non-inhibitory", "Urinary tract infection organisms"],
             ["Selenite F Broth", "Enrichment", "Salmonella, Shigella"]]
    e.append(info_table(media, col_widths=[5*cm, 3.5*cm, 9*cm], header_bg=HexColor("#6A1B9A")))
    e.append(sp(10))

    e.append(Paragraph("5.3 Common Serological Tests", sec_head))
    sero = [["Test", "Disease Detected", "Key Note"],
            ["VDRL / RPR", "Syphilis (screening)", "Treponemal antigen; confirm with TPHA"],
            ["Widal Test", "Typhoid (Salmonella typhi)", "H and O agglutinins; titre >1:160 significant"],
            ["Mantoux / Tuberculin Test", "TB exposure/immunity", "PPD (purified protein derivative); read at 48–72 hrs"],
            ["ELISA", "HIV, HBsAg, HCV, Dengue NS1, etc.", "Enzyme-linked; detects Ag or Ab"],
            ["Western Blot", "HIV confirmation", "Gold standard for HIV confirmation"],
            ["Dengue NS1 Antigen", "Dengue fever (early)", "Days 1–5 of illness"],
            ["HBsAg", "Hepatitis B (surface antigen)", "First marker to appear in acute HBV"],
            ["Anti-HCV", "Hepatitis C antibody", "Confirmed by HCV RNA (PCR)"]]
    e.append(info_table(sero, col_widths=[4.5*cm, 4.5*cm, 8.5*cm], header_bg=TEAL))
    e.append(sp(10))

    e.append(Paragraph("5.4 Important Parasites", sec_head))
    para = [["Parasite", "Disease", "Transmission", "Lab Diagnosis"],
            ["Plasmodium vivax/falciparum", "Malaria", "Anopheles mosquito bite", "Thick/Thin blood smear (Giemsa); RDT"],
            ["Entamoeba histolytica", "Amoebic dysentery", "Faeco-oral (contaminated water)", "Stool microscopy – cysts/trophozoites"],
            ["Giardia lamblia", "Giardiasis", "Faeco-oral (cysts in water)", "Stool microscopy – pear-shaped trophozoites"],
            ["Ascaris lumbricoides", "Ascariasis", "Contaminated food/water/soil", "Stool exam – characteristic eggs"],
            ["Wuchereria bancrofti", "Filariasis", "Culex mosquito", "Night blood smear – microfilariae"],
            ["Taenia solium", "Cysticercosis/Taeniasis", "Undercooked pork", "Stool – proglottids/eggs"]]
    e.append(info_table(para, col_widths=[4.5*cm, 3*cm, 3.5*cm, 6.5*cm], header_bg=HexColor("#6A1B9A")))
    e.append(PageBreak())
    return e


# ── Chapter 6: Biochemistry ───────────────────────────────────

def chapter6():
    e = []
    e.append(ChapterHeader("6", "Biochemistry & Clinical Chemistry", HexColor("#E65100")))
    e.append(sp(10))

    e.append(Paragraph("6.1 Liver Function Tests (LFT)", sec_head))
    lft = [["Test", "Normal Value", "Elevated In"],
           ["Total Bilirubin", "0.2–1.2 mg/dL", "Jaundice, Hepatitis, Haemolysis"],
           ["Direct (Conjugated) Bilirubin", "0–0.3 mg/dL", "Obstructive jaundice, Liver disease"],
           ["Indirect (Unconjugated) Bilirubin", "0.1–1.0 mg/dL", "Haemolytic anaemia, Gilbert's syndrome"],
           ["SGPT / ALT", "7–56 U/L", "Liver cell damage (most specific)"],
           ["SGOT / AST", "10–40 U/L", "Liver, heart, muscle damage"],
           ["Alkaline Phosphatase (ALP)", "44–147 U/L", "Obstructive jaundice, Bone disease"],
           ["GGT", "8–61 U/L", "Alcohol abuse, Cholestasis"],
           ["Serum Albumin", "3.5–5.0 g/dL", "Low = Chronic liver disease, Malnutrition"],
           ["Serum Total Protein", "6.0–8.3 g/dL", "—"]]
    e.append(info_table(lft, col_widths=[5*cm, 4*cm, 8.5*cm], header_bg=HexColor("#E65100")))
    e.append(sp(10))

    e.append(Paragraph("6.2 Renal Function Tests (RFT)", sec_head))
    rft = [["Test", "Normal Value", "Note"],
           ["Serum Creatinine (Male)", "0.7–1.2 mg/dL", "Best indicator of GFR"],
           ["Serum Creatinine (Female)", "0.5–1.0 mg/dL", "—"],
           ["Blood Urea Nitrogen (BUN)", "7–20 mg/dL", "Elevated in Prerenal/Renal azotaemia"],
           ["Serum Uric Acid (Male)", "3.4–7.0 mg/dL", "High in Gout"],
           ["GFR", "~125 mL/min", "CKD: GFR <60 for >3 months"],
           ["Urine Protein", "< 150 mg/day", "Proteinuria in nephrotic syndrome"],
           ["Urine Creatinine Clearance", "85–125 mL/min", "Renal function test"]]
    e.append(info_table(rft, col_widths=[5.5*cm, 4*cm, 8*cm], header_bg=HexColor("#E65100")))
    e.append(sp(10))

    e.append(Paragraph("6.3 Cardiac Markers", sec_head))
    cardiac = [["Marker", "Rises", "Peaks", "Returns to Normal", "Note"],
               ["Troponin I / T", "3–6 hrs", "12–24 hrs", "7–14 days", "Most sensitive + specific for MI"],
               ["CK-MB", "3–6 hrs", "12–24 hrs", "48–72 hrs", "MI reinfarction monitoring"],
               ["Myoglobin", "1–3 hrs", "6–9 hrs", "24 hrs", "First to rise; not cardiac-specific"],
               ["LDH1", "6–12 hrs", "24–48 hrs", "10–14 days", "LDH1 > LDH2 = 'flipped pattern' in MI"],
               ["BNP / NT-proBNP", "—", "—", "—", "Heart failure marker; not MI-specific"]]
    e.append(info_table(cardiac, col_widths=[3.5*cm, 2.5*cm, 2.5*cm, 3.5*cm, 5.5*cm], header_bg=RED))
    e.append(sp(10))

    e.append(Paragraph("6.4 Diabetes & Glucose Tests", sec_head))
    diab = [["Test", "Normal", "Pre-Diabetes", "Diabetes"],
            ["Fasting Blood Glucose (FBG)", "70–99 mg/dL", "100–125 mg/dL", ">= 126 mg/dL"],
            ["Post-Prandial Glucose (2hr OGTT)", "< 140 mg/dL", "140–199 mg/dL", ">= 200 mg/dL"],
            ["HbA1c", "< 5.7%", "5.7–6.4%", ">= 6.5%"],
            ["Random Blood Glucose", "< 140 mg/dL", "—", ">= 200 mg/dL + symptoms"]]
    e.append(info_table(diab, col_widths=[6*cm, 3.5*cm, 3.5*cm, 4.5*cm], header_bg=HexColor("#E65100")))
    e.append(colored_box([
        Paragraph("<b>Remember:</b> HbA1c reflects average blood glucose over the PAST 2–3 MONTHS "
                  "(lifespan of RBC). It is NOT affected by short-term dietary changes.", note_style)
    ], bg=AMBER_LIGHT, border=AMBER))
    e.append(PageBreak())
    return e


# ── Chapter 7: Histopathology ─────────────────────────────────

def chapter7():
    e = []
    e.append(ChapterHeader("7", "Histopathology & Molecular Biology", HexColor("#00695C")))
    e.append(sp(10))

    e.append(Paragraph("7.1 Tissue Processing Steps (In Order)", sec_head))
    steps7 = [("1", "Fixation", "Preserves tissue. 10% Neutral Buffered Formalin (NBF) most common."),
              ("2", "Grossing / Trimming", "Macroscopic examination and cutting of tissue."),
              ("3", "Dehydration", "Removal of water using graded alcohols (70%, 90%, 100%)."),
              ("4", "Clearing", "Replaces alcohol with xylene (makes tissue transparent)."),
              ("5", "Impregnation", "Infiltration with molten paraffin wax under vacuum."),
              ("6", "Embedding", "Tissue placed in paraffin mould; allowed to harden."),
              ("7", "Sectioning", "Microtome cuts 3–5 µm thin sections onto glass slides."),
              ("8", "Deparaffinization", "Xylene removes wax before staining."),
              ("9", "Staining", "H&E (routine), Special stains, IHC as required."),
              ("10", "Mounting", "DPX mountant, coverslip applied.")]
    step_data = [["Step", "Process", "Detail"]] + list(steps7)
    e.append(info_table(step_data, col_widths=[1.5*cm, 4*cm, 12*cm], header_bg=HexColor("#00695C")))
    e.append(sp(10))

    e.append(Paragraph("7.2 Common Histological Stains", sec_head))
    histo_stains = [["Stain", "Purpose", "Color"],
                    ["H & E (Haematoxylin & Eosin)", "Routine staining (Gold Standard)", "Nuclei = Blue; Cytoplasm = Pink"],
                    ["PAS (Periodic Acid-Schiff)", "Glycogen, fungi, basement membranes", "Positive = Magenta"],
                    ["Masson's Trichrome", "Collagen / fibrosis", "Collagen = Blue; Muscle = Red"],
                    ["Congo Red", "Amyloid deposits", "Green birefringence under polarised light"],
                    ["Reticulin Stain (Gordon-Sweet)", "Reticulin fibres, liver architecture", "Fibres = Black"],
                    ["Oil Red O", "Lipids / fat", "Lipids = Red (frozen sections only)"],
                    ["Prussian Blue (Perls')", "Iron / haemosiderin", "Iron = Blue"],
                    ["Alcian Blue", "Acid mucins", "Mucin = Blue"]]
    e.append(info_table(histo_stains, col_widths=[5*cm, 5*cm, 7.5*cm], header_bg=HexColor("#00695C")))
    e.append(sp(10))

    e.append(Paragraph("7.3 Molecular Biology Techniques", sec_head))
    mol = [
        ("PCR (Polymerase Chain Reaction)",
         "Amplifies specific DNA sequences. Uses: infectious disease diagnosis (TB, HIV, COVID-19), "
         "genetic testing. Requires: Template DNA, Primers, dNTPs, Taq polymerase, Thermocycler. "
         "Phases: Denaturation (94°C) → Annealing (~55°C) → Extension (72°C)."),
        ("FISH (Fluorescence In Situ Hybridization)",
         "Detects chromosomal abnormalities using fluorescent probes. Used in HER2 amplification "
         "(breast cancer), BCR-ABL (CML), trisomy detection."),
        ("Southern Blot", "Detects specific DNA sequences. Uses gel electrophoresis + membrane transfer + probe hybridization."),
        ("Western Blot", "Detects specific proteins. HIV confirmatory test. Separates proteins by size (SDS-PAGE)."),
        ("ELISA (Enzyme-Linked Immunosorbent Assay)",
         "Detects antigens or antibodies. Types: Direct, Indirect, Sandwich, Competitive. "
         "Widely used for HIV, HBsAg, dengue, TORCH infections."),
        ("Flow Cytometry",
         "Analyses cell surface markers. Used for: CD4/CD8 count (HIV monitoring), "
         "leukaemia/lymphoma immunophenotyping."),
    ]
    for name, desc in mol:
        e.append(Paragraph(name, sub_head))
        e.append(Paragraph(desc, body))
    e.append(PageBreak())
    return e


# ── Chapter 8: Lab Management ─────────────────────────────────

def chapter8():
    e = []
    e.append(ChapterHeader("8", "Laboratory Management, Quality Control & Safety", HexColor("#4527A0")))
    e.append(sp(10))

    e.append(Paragraph("8.1 Quality Control (QC) in the Laboratory", sec_head))
    qc_points = [
        "QC ensures test accuracy and reliability.",
        "Levey-Jennings chart: Plots QC data over time to detect shifts, trends, and outliers.",
        "Westgard Rules: Statistical rules to accept or reject a QC run (1-2s, 1-3s, 2-2s, R-4s, etc.).",
        "Control material: Assayed or unassayed materials with known values run alongside patient samples.",
        "Calibration: Instruments must be calibrated using certified reference standards.",
        "Internal QC (IQC): Run within the lab daily.",
        "External QC (EQA/EQAS): Proficiency testing through external agencies (e.g., CMC Vellore EQAS).",
        "Accuracy: How close to the true value. Precision: How reproducible the result is.",
        "NABL (National Accreditation Board for Testing and Calibration Laboratories): Indian lab accreditation body.",
    ]
    for pt in qc_points:
        e.append(bullet(pt))
    e.append(sp(10))

    e.append(Paragraph("8.2 Sterilization & Disinfection Methods", sec_head))
    ster = [["Method", "Type", "Temperature/Agent", "Used For"],
            ["Autoclave", "Moist heat sterilization", "121°C, 15 psi, 15–20 min", "Surgical instruments, media, glassware"],
            ["Hot Air Oven", "Dry heat sterilization", "160°C for 1 hr / 170°C for 45 min", "Glassware, metal instruments"],
            ["UV Light", "Radiation", "254 nm wavelength", "Surface/air sterilization in labs/OT"],
            ["Ethylene Oxide (EtO)", "Gas sterilization", "50–60°C", "Heat-sensitive items (plastics, rubber)"],
            ["Glutaraldehyde (2%)", "High-level disinfection", "Room temperature", "Endoscopes, dental instruments"],
            ["Sodium Hypochlorite (bleach)", "Intermediate disinfection", "0.5–1% solution", "Blood spills, surfaces"],
            ["Pasteurization", "Heat (partial)", "63°C/30 min or 72°C/15 sec", "Milk, certain lab reagents"],
            ["Filtration", "Physical (0.22 µm membrane)", "Room temp", "Heat-sensitive liquids, IV fluids"]]
    e.append(info_table(ster, col_widths=[4.5*cm, 3.5*cm, 4*cm, 5.5*cm], header_bg=HexColor("#4527A0")))
    e.append(sp(10))

    e.append(Paragraph("8.3 Biosafety Levels (BSL)", sec_head))
    bsl = [["Level", "Agent Type", "Examples", "Precautions"],
           ["BSL-1", "Non-pathogenic", "E. coli (non-pathogenic), Bacillus subtilis", "Standard lab practice"],
           ["BSL-2", "Moderate risk", "HBV, HCV, Salmonella, Staphylococcus", "PPE, Biohazard cabinets"],
           ["BSL-3", "Serious disease", "M. tuberculosis, HIV, SARS-CoV-2", "BSC Class II, Sealed equipment"],
           ["BSL-4", "Life-threatening", "Ebola, Marburg, Lassa fever", "Full pressure suits, sealed cabinets"]]
    e.append(info_table(bsl, col_widths=[1.5*cm, 3*cm, 5.5*cm, 7.5*cm], header_bg=HexColor("#4527A0")))
    e.append(sp(10))

    e.append(Paragraph("8.4 Standard Precautions & PPE", sec_head))
    ppe_points = [
        "Treat ALL patient specimens as potentially infectious.",
        "Gloves: Wear when handling blood, body fluids, specimens, sharp instruments.",
        "Mask: Surgical mask for respiratory precautions; N95 for TB/airborne.",
        "Eye protection: Goggles/face shield during procedures with splash risk.",
        "Lab coat/Gown: Always in the lab; remove before leaving.",
        "Hand hygiene: Wash hands before and after EVERY patient contact or specimen handling.",
        "Needle-stick injury: Report immediately; wash with soap and water; follow PEP (post-exposure prophylaxis) protocol for HIV/HBV.",
        "Sharps disposal: Puncture-resistant sharps containers (yellow); never recap needles by hand.",
        "Biomedical waste: Segregate into color-coded bins – Yellow (anatomical/infectious), Red (recyclable), Blue (glass), Black (general).",
    ]
    for pt in ppe_points:
        e.append(bullet(pt))
    e.append(PageBreak())
    return e


# ── Chapter 9: Mock Test ──────────────────────────────────────

def chapter9():
    e = []
    e.append(ChapterHeader("9", "Full Mock Test – 100 Questions", RED))
    e.append(sp(8))
    e.append(colored_box([
        Paragraph("<b>Instructions:</b> 100 Questions | 100 Marks | Time: 2 Hours | No Negative Marking | "
                  "Tick the correct answer option. Answers provided at end of chapter.", warn_style)
    ], bg=RED_LIGHT, border=RED))
    e.append(sp(8))

    questions = [
        # GK Section
        ("GK & Aptitude", [
            ("1", "CISF headquarters is located in:", "A) Mumbai", "B) New Delhi*", "C) Hyderabad", "D) Pune"),
            ("2", "Normal blood pH range is:", "A) 6.8–7.0", "B) 7.0–7.2", "C) 7.35–7.45*", "D) 7.5–7.6"),
            ("3", "World Blood Donor Day is observed on:", "A) 7 April", "B) 14 June*", "C) 25 April", "D) 1 December"),
            ("4", "NABL accredits which type of organizations?", "A) Hospitals", "B) Medical colleges", "C) Testing & calibration laboratories*", "D) Pharmaceutical companies"),
            ("5", "15% of 480 =", "A) 62", "B) 72*", "C) 82", "D) 92"),
            ("6", "A train covers 540 km in 6 hours. Speed in m/s:", "A) 20 m/s", "B) 25 m/s*", "C) 30 m/s", "D) 35 m/s"),
            ("7", "SI on Rs. 6000 @ 10% for 2 years:", "A) Rs. 600", "B) Rs. 1000", "C) Rs. 1200*", "D) Rs. 1500"),
            ("8", "If 8 men finish work in 12 days, 16 men finish in:", "A) 6 days*", "B) 8 days", "C) 10 days", "D) 4 days"),
            ("9", "The 'Sunshine Vitamin' is:", "A) Vitamin A", "B) Vitamin B12", "C) Vitamin C", "D) Vitamin D*"),
            ("10", "ICMR stands for:", "A) Indian Council of Medical Research*", "B) Indian Centre for Medical Records", "C) International Council of Medical Radiology", "D) Indian Committee on Medical Regulation"),
        ]),
        ("Human Anatomy & Physiology", [
            ("11", "Normal adult hemoglobin in males:", "A) 10–12 g/dL", "B) 12–14 g/dL", "C) 13–17 g/dL*", "D) 18–20 g/dL"),
            ("12", "Functional unit of the kidney:", "A) Alveolus", "B) Nephron*", "C) Villus", "D) Acinus"),
            ("13", "Salivary amylase digests:", "A) Proteins", "B) Fats", "C) Starch*", "D) Nucleic acids"),
            ("14", "The 'pacemaker' of the heart is the:", "A) AV node", "B) Bundle of His", "C) SA node*", "D) Purkinje fibres"),
            ("15", "Normal platelet count:", "A) 50,000–1,00,000/µL", "B) 1,50,000–4,00,000/µL*", "C) 5,00,000–7,00,000/µL", "D) 10,000–50,000/µL"),
            ("16", "Which organ produces bile?", "A) Gallbladder", "B) Pancreas", "C) Liver*", "D) Spleen"),
            ("17", "Hypothalamus regulates:", "A) Balance", "B) Vision", "C) Body temperature*", "D) Hearing"),
            ("18", "Normal fasting blood glucose:", "A) 40–60 mg/dL", "B) 70–100 mg/dL*", "C) 120–140 mg/dL", "D) 150–180 mg/dL"),
            ("19", "The largest bone in the human body:", "A) Humerus", "B) Tibia", "C) Femur*", "D) Fibula"),
            ("20", "Hormone of 'fight or flight' response:", "A) Insulin", "B) Cortisol", "C) Adrenaline*", "D) Glucagon"),
        ]),
    ]

    for section_name, qs in questions:
        e.append(Paragraph(section_name, sec_head))
        for qno, qtext, a, b, c, d in qs:
            e.append(Paragraph(f"<b>Q{qno}.</b> {qtext}", body))
            options = Table([[Paragraph(a, body), Paragraph(b, body)],
                              [Paragraph(c, body), Paragraph(d, body)]],
                             colWidths=[(W - 2*MARGIN - 20)/2]*2)
            options.setStyle(TableStyle([
                ("TOPPADDING", (0,0), (-1,-1), 1),
                ("BOTTOMPADDING", (0,0), (-1,-1), 1),
                ("LEFTPADDING", (0,0), (-1,-1), 14),
            ]))
            e.append(options)
            e.append(sp(4))

    # Remaining questions as answer-sheet style (for brevity in PDF)
    e.append(Paragraph("Professional Subjects (Q21–Q100)", sec_head))
    prof_qs = [
        "21. EDTA is used as anticoagulant for: A) Coagulation tests  B) CBC*  C) Glucose  D) LFT",
        "22. Universal blood donor group: A) A  B) B  C) AB  D) O*",
        "23. Gram-positive bacteria stain: A) Pink  B) Red  C) Violet*  D) Colourless",
        "24. LJ medium is used for: A) Staphylococcus  B) E. coli  C) M. tuberculosis*  D) Candida",
        "25. VDRL test diagnoses: A) HIV  B) Syphilis*  C) Hepatitis B  D) Malaria",
        "26. Direct Coombs test detects: A) Free antibodies in serum  B) Antibodies coating RBCs*  C) Blood group antigens  D) Complement in plasma",
        "27. Prothrombin Time (PT) tests which pathway? A) Intrinsic  B) Extrinsic*  C) Common  D) Fibrinolytic",
        "28. Best cardiac marker for MI: A) LDH  B) Myoglobin  C) Troponin I/T*  D) CK-BB",
        "29. Gold standard routine stain in histopathology: A) PAS  B) H&E*  C) Congo Red  D) Giemsa",
        "30. PCR amplifies: A) Proteins  B) RNA only  C) Specific DNA sequences*  D) Lipids",
        "31. Autoclave temperature and pressure: A) 100°C / 10 psi  B) 121°C / 15 psi*  C) 160°C / 15 psi  D) 180°C / 20 psi",
        "32. Levey-Jennings chart monitors: A) Patient results  B) QC data over time*  C) Reagent expiry  D) Calibration schedule",
        "33. Normal ESR (male, Westergren): A) 0–5 mm/hr  B) 0–15 mm/hr*  C) 20–30 mm/hr  D) 40–50 mm/hr",
        "34. Dengue NS1 antigen is most useful in: A) 2nd week  B) 3rd week  C) First 5 days*  D) Convalescent phase",
        "35. Sickle cell anaemia: mutation in: A) Alpha chain  B) Beta chain*  C) Delta chain  D) Gamma chain",
        "36. Colour tube for coagulation tests: A) Purple  B) Red  C) Light blue*  D) Grey",
        "37. Serum creatinine (male) normal range: A) 0.2–0.4 mg/dL  B) 0.7–1.2 mg/dL*  C) 2.0–3.5 mg/dL  D) 4.0–5.0 mg/dL",
        "38. HbA1c reflects glucose over: A) 2 weeks  B) 4 weeks  C) 2–3 months*  D) 6 months",
        "39. India ink identifies: A) Candida  B) Aspergillus  C) Cryptococcus neoformans*  D) Histoplasma",
        "40. Widal test is for: A) Malaria  B) Typhoid*  C) Dengue  D) Syphilis",
        "41. ZN stain used for: A) Bacteria  B) Fungi  C) AFB*  D) Parasites",
        "42. PCV normal in adult males: A) 25–35%  B) 36–46%  C) 40–54%*  D) 55–65%",
        "43. Most abundant plasma protein: A) Globulin  B) Fibrinogen  C) Albumin*  D) Prothrombin",
        "44. FISH detects: A) Protein expression  B) Chromosomal abnormalities*  C) Blood group antigens  D) Enzyme activity",
        "45. Malaria is transmitted by: A) Aedes mosquito  B) Culex mosquito  C) Anopheles mosquito*  D) Phlebotomus",
        "46. Congo Red stain used for: A) Fungi  B) Collagen  C) Amyloid*  D) Iron",
        "47. Coagulation factor deficient in Haemophilia A: A) Factor VII  B) Factor VIII*  C) Factor IX  D) Factor X",
        "48. NABL stands for: A) National Accreditation Board for Laboratories  B) National Accreditation Board for Testing & Calibration Laboratories*  C) National Association of Bio-Labs  D) None",
        "49. PPE colour for sharps disposal: A) Black  B) Yellow  C) Red  D) Puncture-resistant yellow container*",
        "50. Normal total bilirubin: A) 0.1–0.5 mg/dL  B) 0.2–1.2 mg/dL*  C) 2.0–3.5 mg/dL  D) 5.0–7.0 mg/dL",
        "51. Rh factor causing HDN: A) Rh-c  B) Rh-D*  C) Rh-E  D) Rh-C",
        "52. Giemsa stain is used for: A) AFB  B) Fungi  C) Blood parasites*  D) Amyloid",
        "53. Sabouraud Dextrose Agar grows: A) M. tuberculosis  B) Salmonella  C) Fungi*  D) Vibrio",
        "54. Standard precautions apply to: A) Only known HIV patients  B) All patients and specimens*  C) Only blood samples  D) Only surgical patients",
        "55. Dehydration in tissue processing uses: A) Xylene  B) Formalin  C) Graded alcohols*  D) Acetone",
        "56. HBsAg is the: A) First antibody to appear  B) First antigen to appear in acute HBV*  C) Confirmatory test for HCV  D) Marker of recovery",
        "57. Alkaline phosphatase (ALP) elevated in: A) Renal failure  B) Heart attack  C) Obstructive jaundice & bone disease*  D) Haemolytic anaemia",
        "58. Which hepatitis is transmitted faeco-orally? A) Hep B  B) Hep C  C) Hep D  D) Hep A*",
        "59. MacConkey agar is used for: A) AFB  B) Fungi  C) Gram-negative bacteria*  D) Viruses",
        "60. BSL-3 organisms include: A) E. coli (non-pathogenic)  B) HBV  C) M. tuberculosis*  D) Ebola",
        "61. Normal serum albumin: A) 1.0–2.5 g/dL  B) 3.5–5.0 g/dL*  C) 6.0–8.0 g/dL  D) 9.0–11.0 g/dL",
        "62. Loop of Henle is found in: A) Liver  B) Lung  C) Kidney – Nephron*  D) Spleen",
        "63. GFR (normal adult): A) 50 mL/min  B) 80 mL/min  C) 125 mL/min*  D) 200 mL/min",
        "64. Masson's trichrome stain demonstrates: A) Amyloid  B) Iron  C) Collagen/fibrosis*  D) Glycogen",
        "65. Myoglobin rises after MI within: A) 30 min  B) 1–3 hours*  C) 6–8 hours  D) 12 hours",
        "66. Reticulocyte count assesses: A) Platelet function  B) Liver synthesis  C) Bone marrow erythropoietic activity*  D) Clotting time",
        "67. Grey tube anticoagulant for glucose: A) Citrate  B) Heparin  C) EDTA  D) NaF + EDTA*",
        "68. Phenylketonuria involves metabolism of: A) Tyrosine  B) Tryptophan  C) Phenylalanine*  D) Leucine",
        "69. Western Blot is gold standard for confirmation of: A) Syphilis  B) Malaria  C) HIV*  D) Dengue",
        "70. Prussian Blue stain detects: A) Lipids  B) Iron/haemosiderin*  C) Amyloid  D) Mucin",
        "71. Serum LDH1 > LDH2 (flipped pattern) seen in: A) Liver disease  B) Myocardial infarction*  C) Pancreatitis  D) Haemolytic anaemia",
        "72. Spore test for autoclave uses: A) E. coli  B) B. stearothermophilus*  C) S. aureus  D) B. anthracis",
        "73. The tube for coagulation tests should be filled to: A) Any level  B) 1/4  C) Half  D) Exactly the fill line (full)*",
        "74. IgA is predominantly found in: A) Blood  B) CSF  C) Body secretions*  D) Lymph nodes",
        "75. Blood group AB is called 'Universal Recipient' because: A) No antigens  B) No antibodies in plasma*  C) Both antigens  D) Anti-A and anti-B absent",
        "76. Normal WBC count: A) 1,000–3,000/µL  B) 4,000–11,000/µL*  C) 12,000–15,000/µL  D) 20,000–25,000/µL",
        "77. ELISA stands for: A) Enzyme-Linked Immunosorbent Assay*  B) Electrolyte-Linked Immune Serum Assay  C) Enzymatic Labeling Immunoassay  D) None",
        "78. Ascaris lumbricoides is transmitted via: A) Mosquito bite  B) Contaminated food/water*  C) Skin contact  D) Airborne",
        "79. Formalin fixation preserves tissue by: A) Freezing  B) Dehydrating  C) Cross-linking proteins*  D) Adding wax",
        "80. High LDL cholesterol indicates risk of: A) Pancreatitis  B) Kidney failure  C) Cardiovascular disease*  D) Liver cirrhosis",
        "81. Urine output < 400 mL/day is called: A) Anuria  B) Polyuria  C) Oliguria*  D) Nocturia",
        "82. Normal aPTT: A) 8–12 seconds  B) 11–14 seconds  C) 25–35 seconds*  D) 50–60 seconds",
        "83. Chocolate agar is used for: A) Salmonella  B) Haemophilus & Neisseria*  C) Fungi  D) E. coli",
        "84. Mast cells produce: A) Insulin  B) Cortisol  C) Heparin*  D) Thyroxine",
        "85. Haematopoiesis occurs in: A) Liver (adults)  B) Yellow bone marrow  C) Red bone marrow*  D) Spleen (adults)",
        "86. Direct bilirubin is: A) Unconjugated  B) Conjugated*  C) Delta bilirubin  D) Albumin-bound",
        "87. TCBS agar selects for: A) Salmonella  B) Vibrio*  C) Fungi  D) Enterococcus",
        "88. Normal serum uric acid in males: A) 1–2 mg/dL  B) 3.4–7.0 mg/dL*  C) 8–10 mg/dL  D) 10–15 mg/dL",
        "89. ESR is raised in: A) Polycythaemia  B) Sickle cell disease  C) Inflammation and infection*  D) Dehydration",
        "90. Thalassaemia is best diagnosed by: A) Serum iron  B) Ferritin  C) HPLC or Hb electrophoresis*  D) Bone marrow biopsy",
        "91. Lecithin:Sphingomyelin ratio is used to assess: A) Liver maturity  B) Lung maturity*  C) Kidney function  D) Brain development",
        "92. HIV enters host cell via: A) CD8 receptor  B) CD4 receptor*  C) CD19 receptor  D) CD56 receptor",
        "93. Normal BUN level: A) 2–5 mg/dL  B) 7–20 mg/dL*  C) 25–35 mg/dL  D) 40–60 mg/dL",
        "94. In DIC, which test is most diagnostic? A) BT  B) CT  C) D-dimer*  D) Hematocrit",
        "95. Cryostat is used for: A) Permanent sections  B) Frozen sections*  C) Electron microscopy  D) Cell cultures",
        "96. TORCH infections include: A) Toxoplasma, Rubella, CMV, HSV*  B) TB, Rabies, Cholera, Hepatitis  C) Typhoid, Rotavirus, Chikungunya, HIV  D) None",
        "97. For blood culture, which bottle is used first? A) Anaerobic  B) Aerobic*  C) Paediatric  D) Fungal",
        "98. RT-PCR detects: A) DNA only  B) Proteins  C) RNA (via reverse transcription)*  D) Lipids",
        "99. Normal INR for healthy individual: A) 0.2–0.5  B) 0.8–1.2*  C) 2.0–3.0  D) 4.0–5.0",
        ("100. The best method to confirm Cryptococcus neoformans infection is:",
         "A) Gram stain  B) ZN stain  C) India ink + culture*  D) PAS stain"),
    ]
    for q in prof_qs:
        if isinstance(q, tuple):
            e.append(Paragraph(f"<b>{q[0]}</b> {q[1]}", body))
        else:
            e.append(Paragraph(q.replace("*", " ✓"), body))
        e.append(sp(2))

    e.append(sp(8))
    e.append(colored_box([
        Paragraph("<b>Note:</b> Correct answers are marked with * or ✓ in the question text above. "
                  "Score >= 70/100 to be strongly competitive for selection.", note_style)
    ], bg=GREEN_LIGHT, border=GREEN))
    e.append(PageBreak())
    return e


# ── Chapter 10: Quick Revision ────────────────────────────────

def chapter10():
    e = []
    e.append(ChapterHeader("10", "Quick Revision Tables & Key Reference Values", HexColor("#BF360C")))
    e.append(sp(10))

    e.append(Paragraph("10.1 Complete Blood Count – Quick Reference", sec_head))
    cbc = [["Parameter", "Male", "Female", "Significance"],
           ["Hemoglobin", "13–17 g/dL", "12–15 g/dL", "Anaemia / Polycythaemia"],
           ["RBC Count", "4.5–5.5 million/µL", "3.8–5.0 million/µL", "Anaemia assessment"],
           ["PCV / Hematocrit", "40–54%", "36–46%", "Blood volume ratio"],
           ["MCV", "80–100 fL", "80–100 fL", "Micro/Macro/Normocytic"],
           ["MCH", "27–33 pg", "27–33 pg", "Hypochromic if low"],
           ["MCHC", "32–36 g/dL", "32–36 g/dL", "Hypochromic if low"],
           ["WBC Count", "4,000–11,000/µL", "4,000–11,000/µL", "Infection/Leukemia"],
           ["Platelet Count", "1.5–4.0 lakh/µL", "1.5–4.0 lakh/µL", "Bleeding/Clotting"],
           ["ESR (Westergren)", "0–15 mm/hr", "0–20 mm/hr", "Inflammation marker"],
           ["Reticulocyte Count", "0.5–1.5%", "0.5–1.5%", "Marrow activity"]]
    e.append(info_table(cbc, col_widths=[4.5*cm, 3*cm, 3*cm, 7*cm], header_bg=DARK_BLUE))
    e.append(sp(10))

    e.append(Paragraph("10.2 High-Yield One-Liners for Last-Minute Revision", sec_head))
    one_liners = [
        "Troponin I/T = Most sensitive + specific marker for MI",
        "HbA1c reflects glucose control over 2–3 months (RBC lifespan)",
        "EDTA tube (Purple) = CBC, HbA1c, Blood film",
        "Citrate tube (Light blue) = PT, aPTT, coagulation studies",
        "ZN stain = AFB (M. tuberculosis stains red on blue background)",
        "India ink = Cryptococcus neoformans (halo/capsule visible)",
        "VDRL = Syphilis screening | TPHA = Syphilis confirmation",
        "Widal test: O antigen (current infection) + H antigen (past infection or immunization)",
        "LJ medium = M. tuberculosis (slow growth, 4–8 weeks)",
        "MacConkey agar: lactose fermenters = pink, non-fermenters = colourless",
        "Group O = Universal Donor (no ABO antigens on RBCs)",
        "Group AB = Universal Recipient (no ABO antibodies in plasma)",
        "Direct Coombs test = IgG/complement on RBC surface (autoimmune haemolytic anaemia)",
        "Hemophilia A = Factor VIII deficiency | Hemophilia B = Factor IX deficiency",
        "Sickle cell: Glu→Val mutation at position 6 of beta-globin",
        "H&E: Haematoxylin = blue nuclei | Eosin = pink cytoplasm",
        "Congo red + polarised light = Apple-green birefringence = AMYLOID",
        "PCR phases: Denaturation (94°C) → Annealing (~55°C) → Extension (72°C)",
        "FISH = chromosomal abnormalities / gene amplification (HER2, BCR-ABL)",
        "Autoclave: 121°C, 15 psi, 15–20 min (moist heat sterilization)",
        "EtO gas = heat-sensitive items (plastics, rubber, catheters)",
        "NABL = Indian accreditation for testing labs | NABH = Hospitals",
        "BSL-3 includes: M. tuberculosis, HIV, SARS-CoV-2",
        "Dengue NS1: positive in first 5 days | IgM: days 5–14",
        "Malaria: Giemsa-stained thick & thin smear + RDT (HRP-2 / pLDH)",
        "Normal fasting glucose: 70–100 mg/dL | Diabetes: ≥ 126 mg/dL",
        "GFR < 60 mL/min for > 3 months = Chronic Kidney Disease (CKD)",
        "LDH1 > LDH2 = 'flipped pattern' = Myocardial Infarction",
        "IgA = secretory (breast milk, saliva, tears, mucous membranes)",
        "Levey-Jennings chart = visual QC control chart; Westgard rules = statistical acceptance/rejection",
    ]
    for i, ol in enumerate(one_liners, 1):
        e.append(Paragraph(f"<b>{i:02d}.</b>  {ol}", key_style))

    e.append(sp(10))
    e.append(Paragraph("10.3 Exam Strategy Tips", sec_head))
    tips = [
        "Allocate time: GK (~18 min) | Anatomy (~18 min) | Professional (64 min). Review in final 20 min.",
        "No negative marking – ATTEMPT ALL QUESTIONS. Never leave any blank.",
        "Read all 4 options before selecting. Eliminate obviously wrong options first.",
        "For 'BEST' or 'MOST' questions, think of the most direct/specific answer.",
        "Memorise normal reference values – at least 5 questions come from these directly.",
        "Focus on: Hematology tubes & anticoagulants, Staining techniques, Serological tests, QC methods.",
        "Revise disease-organism associations (LJ medium = TB, TCBS = Vibrio, SDA = Fungi).",
        "Practice 25 aptitude problems daily: percentage, ratio, SI/CI, time-work.",
    ]
    for t in tips:
        e.append(bullet(t))

    e.append(sp(12))
    e.append(colored_box([
        Paragraph("<b>Official Websites to Track Exam Dates:</b>", sub_head),
        Paragraph("CISF: cisfrectt.cisf.gov.in", body),
        Paragraph("BSF: rectt.bsf.gov.in", body),
        Paragraph("Target Score: 70+ out of 100 for strong selection probability.", body),
    ], bg=GREEN_LIGHT, border=GREEN))

    e.append(sp(20))
    e.append(HRFlowable(width="100%", thickness=1, color=GREY_MID))
    e.append(sp(6))
    e.append(Paragraph("ASI Lab Technician Study Guide 2026 | CISF & BSF Paramedical Recruitment",
                        S("Footer2", fontName="Helvetica-Oblique", fontSize=8.5,
                          textColor=GREY_MID, alignment=TA_CENTER)))
    return e


# ── Page template with header/footer ──────────────────────────

def on_first_page(canvas, doc):
    pass

def on_later_pages(canvas, doc):
    canvas.saveState()
    canvas.setFont("Helvetica", 7.5)
    canvas.setFillColor(GREY_MID)
    canvas.drawString(MARGIN, 0.6*cm, "ASI Lab Technician Study Guide 2026 | CISF & BSF")
    canvas.drawRightString(W - MARGIN, 0.6*cm, f"Page {doc.page}")
    canvas.setStrokeColor(HexColor("#B0BEC5"))
    canvas.setLineWidth(0.5)
    canvas.line(MARGIN, 0.85*cm, W - MARGIN, 0.85*cm)
    canvas.restoreState()


# ── Build ──────────────────────────────────────────────────────

def build():
    doc = SimpleDocTemplate(
        OUTPUT,
        pagesize=A4,
        leftMargin=MARGIN, rightMargin=MARGIN,
        topMargin=MARGIN, bottomMargin=1.5*cm,
        title="ASI Lab Technician Study Guide 2026",
        author="Orris – CISF/BSF Exam Preparation",
        subject="ASI Lab Technician Comprehensive Study Guide",
    )

    story = []
    story += cover_page()
    story += chapter1()
    story += chapter2()
    story += chapter3()
    story += chapter4()
    story += chapter5()
    story += chapter6()
    story += chapter7()
    story += chapter8()
    story += chapter9()
    story += chapter10()

    doc.build(story, onFirstPage=on_first_page, onLaterPages=on_later_pages)
    print(f"PDF created: {OUTPUT}")

build()
Running Command

cd /tmp/workspace/asi-lab-tech-guide && python build_guide.py 2>&1

Running Command

ls -lh /tmp/workspace/asi-lab-tech-guide/

Your comprehensive study guide PDF is ready! Here's a summary of everything packed inside:

Download Your PDF

ASI Lab Technician Study Guide 2026

PDF Document · PDF


What's Inside (10 Full Chapters)

ChapterContents
Ch 1Exam Overview, CISF/BSF key dates, eligibility, selection process, PST norms
Ch 2GK & Aptitude - important topics, all key formulas, 5 solved practice problems
Ch 3Human Anatomy & Physiology - full normal reference values table + all body systems
Ch 4Hematology & Blood Banking - anticoagulants, ABO system, coagulation tests, Hb disorders
Ch 5Microbiology, Immunology & Parasitology - staining, culture media, serology, parasites
Ch 6Biochemistry - LFT, RFT, cardiac markers (Troponin), diabetes & glucose tests
Ch 7Histopathology & Molecular Biology - tissue processing steps, stains, PCR, FISH, ELISA
Ch 8Lab Management - QC, Levey-Jennings, sterilization methods, BSL levels, PPE & safety
Ch 9Full 100-question Mock Test with answers marked
Ch 10Quick revision one-liners (30 high-yield facts) + CBC reference table + exam strategy tips
The PDF uses color-coded chapter banners, formatted tables, highlighted warning/tip boxes, and a professional cover page. Best of luck with your exam!

That good but make it a specific subject only

Asking for Preferences
Writing File

~/asi-lab-tech-guide/build_anatomy.py


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

OUTPUT = "/tmp/workspace/asi-lab-tech-guide/ASI_Human_Anatomy_Physiology_Guide_2026.pdf"

W, H = A4
MARGIN = 2 * cm

# ── Colour palette ─────────────────────────────────────────────
NAVY       = HexColor("#0D1B4B")
ROYAL      = HexColor("#1565C0")
SKY        = HexColor("#1E88E5")
ICE        = HexColor("#E3F2FD")
TEAL       = HexColor("#00796B")
TEAL_LIGHT = HexColor("#E0F2F1")
RED        = HexColor("#B71C1C")
RED_LIGHT  = HexColor("#FFEBEE")
AMBER      = HexColor("#E65100")
AMBER_LT   = HexColor("#FFF3E0")
GREEN      = HexColor("#1B5E20")
GREEN_LT   = HexColor("#E8F5E9")
PURPLE     = HexColor("#4A148C")
PURPLE_LT  = HexColor("#F3E5F5")
GREY       = HexColor("#37474F")
GREY_MID   = HexColor("#546E7A")
GREY_LT    = HexColor("#ECEFF1")
WHITE      = colors.white

# ── Styles ─────────────────────────────────────────────────────
def S(name, **kw):
    return ParagraphStyle(name, **kw)

cover_title  = S("CT", fontName="Helvetica-Bold", fontSize=32, textColor=WHITE, alignment=TA_CENTER, leading=40, spaceAfter=8)
cover_sub    = S("CS", fontName="Helvetica", fontSize=14, textColor=HexColor("#BBDEFB"), alignment=TA_CENTER, leading=20, spaceAfter=6)
cover_badge  = S("CB", fontName="Helvetica-Bold", fontSize=11, textColor=HexColor("#FFD54F"), alignment=TA_CENTER, spaceAfter=4)
sec_head     = S("SH", fontName="Helvetica-Bold", fontSize=13, textColor=NAVY, spaceBefore=14, spaceAfter=6, leading=17)
sub_head     = S("SuH", fontName="Helvetica-Bold", fontSize=11, textColor=ROYAL, spaceBefore=10, spaceAfter=4, leading=15)
body         = S("B", fontName="Helvetica", fontSize=9.5, textColor=GREY, leading=14, spaceAfter=4, alignment=TA_JUSTIFY)
bullet_s     = S("Bu", fontName="Helvetica", fontSize=9.5, textColor=GREY, leading=13, spaceAfter=3, leftIndent=14)
key_s        = S("Ke", fontName="Helvetica-Bold", fontSize=9.5, textColor=GREEN, leading=13, spaceAfter=3, leftIndent=14)
note_s       = S("No", fontName="Helvetica-Oblique", fontSize=9, textColor=PURPLE, leading=13, spaceAfter=4, leftIndent=10)
warn_s       = S("Wa", fontName="Helvetica-Bold", fontSize=9.5, textColor=RED, leading=13, spaceAfter=3, leftIndent=10)
mcq_q        = S("MQ", fontName="Helvetica-Bold", fontSize=9.5, textColor=NAVY, leading=14, spaceAfter=2, spaceBefore=6)
mcq_a        = S("MA", fontName="Helvetica", fontSize=9.5, textColor=GREY, leading=13, spaceAfter=1, leftIndent=12)
mcq_ans      = S("MAN", fontName="Helvetica-Bold", fontSize=9.5, textColor=GREEN, leading=13, spaceAfter=4, leftIndent=12)

# ── Helpers ────────────────────────────────────────────────────
class ChapterHeader(Flowable):
    def __init__(self, number, title, color=NAVY, height=1.3*cm):
        Flowable.__init__(self)
        self.number = number; self.title = title
        self.color = color;   self.bh = height
    def draw(self):
        c = self.canv
        c.setFillColor(self.color)
        c.roundRect(0, 0, self.width, self.bh, 8, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont("Helvetica-Bold", 14)
        c.drawString(14, self.bh * 0.28, f"Chapter {self.number}: {self.title}")
    def wrap(self, aw, ah):
        self.width = aw; return aw, self.bh

class SectionBand(Flowable):
    def __init__(self, title, color=SKY, height=0.65*cm):
        Flowable.__init__(self)
        self.title = title; self.color = color; self.bh = height
    def draw(self):
        c = self.canv
        c.setFillColor(self.color)
        c.roundRect(0, 0, self.width, self.bh, 5, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont("Helvetica-Bold", 10)
        c.drawString(10, self.bh * 0.22, self.title)
    def wrap(self, aw, ah):
        self.width = aw; return aw, self.bh

def tbl(rows, cw=None, hbg=NAVY, alt=ICE):
    if cw is None:
        n = len(rows[0]); cw = [(W - 2*MARGIN)/n]*n
    t = Table(rows, colWidths=cw, repeatRows=1)
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), hbg),
        ("TEXTCOLOR", (0,0), (-1,0), WHITE),
        ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE", (0,0), (-1,0), 8.5),
        ("ALIGN", (0,0), (-1,-1), "CENTER"),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("FONTNAME", (0,1), (-1,-1), "Helvetica"),
        ("FONTSIZE", (0,1), (-1,-1), 8.5),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, alt]),
        ("GRID", (0,0), (-1,-1), 0.5, HexColor("#B0BEC5")),
        ("TOPPADDING", (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING", (0,0), (-1,-1), 6),
        ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ])); return t

def box(items, bg=ICE, border=SKY):
    data = [[i] for i in items]
    t = Table(data, colWidths=[W - 2*MARGIN])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("BOX", (0,0), (-1,-1), 1.2, border),
        ("TOPPADDING", (0,0), (-1,-1), 7),
        ("BOTTOMPADDING", (0,0), (-1,-1), 7),
        ("LEFTPADDING", (0,0), (-1,-1), 12),
        ("RIGHTPADDING", (0,0), (-1,-1), 12),
    ])); return t

def bu(text): return Paragraph(f"&#x2022;  {text}", bullet_s)
def kl(text): return Paragraph(f"&#x2714;  {text}", key_s)
def sp(n=6):  return Spacer(1, n)
def pg():     return PageBreak()

# ══════════════════════════════════════════════════════════════
# COVER
# ══════════════════════════════════════════════════════════════
def cover():
    e = []
    e.append(sp(18))
    banner = [
        [Paragraph("CISF / BSF  |  ASI Lab Technician 2026", cover_badge)],
        [Paragraph("Human Anatomy &\nPhysiology", cover_title)],
        [Paragraph("In-Depth Study Guide", cover_sub)],
        [sp(4)],
        [Paragraph("25 Questions · 25 Marks · Section B of Written Exam", cover_badge)],
    ]
    bt = Table(banner, colWidths=[W - 2*MARGIN])
    bt.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), NAVY),
        ("TOPPADDING", (0,0), (-1,-1), 6),
        ("BOTTOMPADDING", (0,0), (-1,-1), 6),
        ("LEFTPADDING", (0,0), (-1,-1), 20),
        ("RIGHTPADDING", (0,0), (-1,-1), 20),
    ]))
    e.append(bt); e.append(sp(16))

    feat = [
        ("10 Body Systems", "Complete coverage with\nclinical relevance"),
        ("Normal Values", "All reference ranges\nyou must memorise"),
        ("Diagrams in Text", "Labelled descriptions\nof key structures"),
        ("50 MCQs + Answers", "Full mock section with\nexplanations"),
    ]
    fc = [[Paragraph(
        f"<b><font size='10'>{t}</font></b><br/><font size='8.5' color='#455A64'>{v}</font>", body
    )] for t,v in feat]
    ft = Table([fc], colWidths=[(W-2*MARGIN)/4]*4)
    ft.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), ICE),
        ("BOX", (0,0), (-1,-1), 1, SKY),
        ("LINEAFTER", (0,0), (-3,-1), 0.5, SKY),
        ("ALIGN", (0,0), (-1,-1), "CENTER"),
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("TOPPADDING", (0,0), (-1,-1), 10),
        ("BOTTOMPADDING", (0,0), (-1,-1), 10),
    ]))
    e.append(ft); e.append(sp(14))

    chapters = [
        "Ch 1 – Introduction: Levels of Organisation & Cell Biology",
        "Ch 2 – Cardiovascular System",
        "Ch 3 – Respiratory System",
        "Ch 4 – Renal / Urinary System",
        "Ch 5 – Digestive System & Liver",
        "Ch 6 – Endocrine System",
        "Ch 7 – Nervous System & Special Senses",
        "Ch 8 – Musculoskeletal System & Blood",
        "Ch 9 – Reproductive & Immune Systems",
        "Ch 10 – Quick-Reference Tables + 50-Question Mock Test",
    ]
    toc = S("TOC", fontName="Helvetica", fontSize=10, textColor=GREY, leading=19, leftIndent=14)
    for ch in chapters:
        e.append(Paragraph(f"&#x25B6;  {ch}", toc))
    e.append(sp(20))
    e.append(Paragraph("Prepared for: ASI Paramedical Exam 2026 — CISF & BSF",
        S("F", fontName="Helvetica-Oblique", fontSize=8.5, textColor=GREY_MID, alignment=TA_CENTER)))
    e.append(pg()); return e

# ══════════════════════════════════════════════════════════════
# CH 1 – CELL & ORGANISATION
# ══════════════════════════════════════════════════════════════
def ch1():
    e = []
    e.append(ChapterHeader("1", "Introduction: Levels of Organisation & Cell Biology", NAVY))
    e.append(sp(10))

    e.append(Paragraph("1.1 Levels of Structural Organisation", sec_head))
    levels = [["Level", "Definition", "Example"],
              ["Chemical / Atomic", "Atoms and molecules", "H2O, DNA, ATP, glucose"],
              ["Cellular", "Basic unit of life", "Neurons, RBCs, hepatocytes"],
              ["Tissue", "Group of similar cells", "Epithelial, connective, muscle, nervous"],
              ["Organ", "Two or more tissue types", "Heart, liver, kidney, lung"],
              ["Organ System", "Related organs working together", "Cardiovascular, digestive, nervous"],
              ["Organism", "All organ systems combined", "Human body"]]
    e.append(tbl(levels, cw=[4*cm, 6*cm, 7.5*cm]))
    e.append(sp(10))

    e.append(Paragraph("1.2 The Cell – Key Organelles & Functions", sec_head))
    organelles = [["Organelle", "Function", "Clinical Note"],
                  ["Nucleus", "Contains DNA; controls cell activity", "Absence = RBC (anucleate)"],
                  ["Mitochondria", "ATP production (cellular respiration)", "Called 'powerhouse of cell'"],
                  ["Ribosomes", "Protein synthesis", "RER-bound (secretory proteins)"],
                  ["Rough ER (RER)", "Protein synthesis + folding", "Abundant in secretory cells"],
                  ["Smooth ER (SER)", "Lipid synthesis, detoxification", "Abundant in liver, steroid cells"],
                  ["Golgi Apparatus", "Packaging and secretion of proteins", "'Post office' of the cell"],
                  ["Lysosomes", "Intracellular digestion; contain hydrolytic enzymes", "Failure → lysosomal storage diseases"],
                  ["Cell Membrane", "Selective permeability; receptor site", "Phospholipid bilayer"],
                  ["Cytoskeleton", "Cell shape, movement, organelle transport", "Actin, tubulin, intermediate filaments"],
                  ["Centrioles", "Cell division (mitosis/meiosis)", "Form spindle fibres"]]
    e.append(tbl(organelles, cw=[4*cm, 6*cm, 7.5*cm]))
    e.append(sp(10))

    e.append(Paragraph("1.3 Types of Body Tissues", sec_head))
    tissues = [["Tissue Type", "Sub-types", "Location / Function"],
               ["Epithelial", "Simple, Stratified, Squamous, Cuboidal, Columnar, Ciliated", "Covers surfaces; absorption, secretion, protection"],
               ["Connective", "Loose, Dense, Adipose, Cartilage, Bone, Blood", "Supports, binds, fills spaces; immune defence"],
               ["Muscle", "Skeletal (voluntary), Cardiac (involuntary, striated), Smooth (involuntary)", "Movement, pump blood, peristalsis"],
               ["Nervous", "Neurons + Neuroglia (Astrocytes, Microglia, Oligodendrocytes, Schwann cells)", "Electrical impulse transmission, coordination"]]
    e.append(tbl(tissues, cw=[3*cm, 6*cm, 8.5*cm]))
    e.append(sp(8))
    e.append(box([Paragraph("<b>Remember:</b> Epithelial tissue has NO blood supply (avascular) – it gets nutrients by diffusion from underlying connective tissue.", note_s)], bg=AMBER_LT, border=AMBER))
    e.append(pg())
    return e

# ══════════════════════════════════════════════════════════════
# CH 2 – CARDIOVASCULAR
# ══════════════════════════════════════════════════════════════
def ch2():
    e = []
    e.append(ChapterHeader("2", "Cardiovascular System", HexColor("#B71C1C")))
    e.append(sp(10))

    e.append(Paragraph("2.1 Structure of the Heart", sec_head))
    e.append(Paragraph(
        "The heart is a hollow, muscular organ located in the mediastinum (middle of the thorax), "
        "slightly to the left. It is enclosed in the pericardium (double-walled fibroserous sac). "
        "The heart wall consists of three layers: Epicardium (outer), Myocardium (middle, thickest – muscle), "
        "and Endocardium (inner lining).", body))
    heart_str = [["Chamber", "Type of Blood", "Receives From", "Pumps To"],
                 ["Right Atrium", "Deoxygenated", "Superior/Inferior vena cava + coronary sinus", "Right ventricle (via tricuspid valve)"],
                 ["Right Ventricle", "Deoxygenated", "Right atrium", "Pulmonary artery → Lungs (via pulmonary valve)"],
                 ["Left Atrium", "Oxygenated", "4 Pulmonary veins (from lungs)", "Left ventricle (via mitral/bicuspid valve)"],
                 ["Left Ventricle", "Oxygenated", "Left atrium", "Aorta → Systemic circulation (via aortic valve)"]]
    e.append(tbl(heart_str, cw=[3*cm, 3*cm, 5.5*cm, 6*cm], hbg=RED))
    e.append(sp(6))
    e.append(box([Paragraph("<b>Valve mnemonic:</b> 'Try Pulling My Aorta' → Tricuspid (R AV), Pulmonary (R semilunar), Mitral/Bicuspid (L AV), Aortic (L semilunar).", note_s)], bg=RED_LIGHT, border=RED))
    e.append(sp(10))

    e.append(Paragraph("2.2 Cardiac Conduction System (Electrical Pathway)", sec_head))
    conduction = [["Node / Structure", "Location", "Role"],
                  ["SA Node (Pacemaker)", "Right atrium wall", "Initiates impulse; 60–100/min (sinus rhythm)"],
                  ["AV Node", "Base of right atrium (interatrial septum)", "Delays impulse 0.1 sec; allows atrial contraction first"],
                  ["Bundle of His", "Interventricular septum", "Carries impulse to ventricles"],
                  ["Right & Left Bundle Branches", "Along interventricular septum", "Distribute impulse to ventricle walls"],
                  ["Purkinje Fibres", "Ventricular myocardium", "Rapid final spread; causes ventricular contraction"]]
    e.append(tbl(conduction, cw=[4.5*cm, 5*cm, 8*cm], hbg=RED))
    e.append(sp(8))
    e.append(box([
        Paragraph("<b>ECG Wave Meanings:</b>", sub_head),
        Paragraph("P wave = Atrial depolarisation (SA node fires)", body),
        Paragraph("QRS complex = Ventricular depolarisation (Bundle branches → Purkinje)", body),
        Paragraph("T wave = Ventricular repolarisation", body),
        Paragraph("PR interval = AV node delay (Normal: 0.12–0.20 sec)", body),
        Paragraph("QRS duration = Normal < 0.12 sec (broad QRS = bundle branch block)", body),
    ], bg=RED_LIGHT, border=RED))
    e.append(sp(10))

    e.append(Paragraph("2.3 Blood Pressure, Pulse & Normal Values", sec_head))
    cv_vals = [["Parameter", "Normal Value", "Abnormal States"],
               ["Blood Pressure", "120/80 mmHg", "Hypertension >140/90; Hypotension <90/60"],
               ["Pulse Rate", "60–100 beats/min", "Bradycardia <60; Tachycardia >100"],
               ["Stroke Volume", "70 mL/beat", "Reduced in heart failure"],
               ["Cardiac Output", "5 L/min (= SV × HR)", "CO = 70 mL × 72/min ≈ 5 L/min"],
               ["Systolic pressure", "Pressure during ventricular contraction", "Reflects cardiac output"],
               ["Diastolic pressure", "Pressure during ventricular relaxation", "Reflects peripheral resistance"],
               ["Pulse Pressure", "Systolic – Diastolic (Normal 40 mmHg)", "Widened in aortic regurgitation"],
               ["Mean Arterial Pressure (MAP)", "~93 mmHg (Diastolic + 1/3 Pulse pressure)", "Perfusion pressure for organs"]]
    e.append(tbl(cv_vals, cw=[4.5*cm, 5*cm, 8*cm], hbg=RED))
    e.append(sp(10))

    e.append(Paragraph("2.4 Blood Vessels", sec_head))
    vessels = [["Vessel", "Wall", "Carries", "Key Feature"],
               ["Arteries", "Thick, muscular, elastic", "Oxygenated blood (except pulmonary artery)", "High pressure; pulsatile flow"],
               ["Arterioles", "Smooth muscle", "Oxygenated to capillaries", "Main resistance vessels; control BP"],
               ["Capillaries", "Single endothelial cell layer", "Exchange of O2, CO2, nutrients, waste", "Site of gas and nutrient exchange"],
               ["Venules", "Thin wall", "Deoxygenated from capillaries", "Low pressure"],
               ["Veins", "Thin wall; valves present", "Deoxygenated blood (except pulmonary vein)", "Capacitance vessels; contain 60-70% blood"],
               ["Pulmonary artery", "Carries deoxygenated blood", "From right ventricle to lungs", "Only artery carrying deoxygenated blood"],
               ["Pulmonary vein", "Carries oxygenated blood", "From lungs to left atrium", "Only vein carrying oxygenated blood"]]
    e.append(tbl(vessels, cw=[3*cm, 3.5*cm, 4.5*cm, 6.5*cm], hbg=RED))
    e.append(pg())
    return e

# ══════════════════════════════════════════════════════════════
# CH 3 – RESPIRATORY
# ══════════════════════════════════════════════════════════════
def ch3():
    e = []
    e.append(ChapterHeader("3", "Respiratory System", HexColor("#006064")))
    e.append(sp(10))

    e.append(Paragraph("3.1 Anatomy of the Respiratory Tract", sec_head))
    resp_anat = [["Structure", "Description", "Function"],
                 ["Nasal cavity", "Air enters; lined with mucosa and cilia", "Filters, warms, humidifies air"],
                 ["Pharynx", "Throat; nasopharynx + oropharynx + laryngopharynx", "Passage for air and food"],
                 ["Larynx", "Voice box; contains vocal cords; epiglottis above", "Sound production; prevents food entry"],
                 ["Trachea", "C-shaped cartilage rings; ciliated epithelium", "Airway to bronchi; mucociliary clearance"],
                 ["Primary Bronchi", "Left and right; right is wider, shorter, more vertical", "Air to each lung"],
                 ["Secondary Bronchi", "One per lobe (3 right, 2 left)", "Air to lobes"],
                 ["Bronchioles", "No cartilage; smooth muscle", "Regulate airflow; spasm = asthma"],
                 ["Terminal Bronchioles", "Last conducting airways", "Lead to alveolar ducts"],
                 ["Alveoli", "300 million tiny air sacs; type I and II pneumocytes", "Gas exchange (O2/CO2)"]]
    e.append(tbl(resp_anat, cw=[4*cm, 5.5*cm, 8*cm], hbg=HexColor("#006064")))
    e.append(sp(8))
    e.append(box([
        Paragraph("<b>Type I Pneumocytes</b> = Flat; form the alveolar wall; site of gas exchange (95% of surface area).", body),
        Paragraph("<b>Type II Pneumocytes</b> = Cuboidal; produce surfactant (dipalmitoyl phosphatidylcholine). Surfactant reduces surface tension, preventing alveolar collapse.", body),
        Paragraph("<b>Clinical:</b> Lack of surfactant in premature infants → Respiratory Distress Syndrome (RDS / Hyaline membrane disease).", warn_s),
    ], bg=TEAL_LIGHT, border=TEAL))
    e.append(sp(10))

    e.append(Paragraph("3.2 Lung Volumes & Capacities", sec_head))
    volumes = [["Parameter", "Normal Value", "Definition"],
               ["Tidal Volume (TV)", "500 mL", "Air breathed in/out in one normal breath"],
               ["Inspiratory Reserve Volume (IRV)", "3000 mL", "Extra air inhaled beyond normal inspiration"],
               ["Expiratory Reserve Volume (ERV)", "1100 mL", "Extra air exhaled beyond normal expiration"],
               ["Residual Volume (RV)", "1200 mL", "Air remaining after maximal expiration (cannot be exhaled)"],
               ["Inspiratory Capacity (IC)", "TV + IRV = 3500 mL", "Total air that can be inspired"],
               ["Functional Residual Capacity (FRC)", "ERV + RV = 2300 mL", "Air remaining after normal expiration"],
               ["Vital Capacity (VC)", "TV + IRV + ERV = 4600 mL", "Maximum air exhaled after maximal inspiration"],
               ["Total Lung Capacity (TLC)", "VC + RV = 5800 mL", "Total air in lungs at maximal inspiration"],
               ["FEV1 / FVC ratio", "≥ 0.70 (70%)", "Obstructive disease <70%; Restrictive disease >70%"]]
    e.append(tbl(volumes, cw=[5*cm, 3.5*cm, 9*cm], hbg=HexColor("#006064")))
    e.append(sp(10))

    e.append(Paragraph("3.3 Gas Exchange & Transport", sec_head))
    e.append(Paragraph(
        "Oxygen transport: 97% as oxyhaemoglobin (HbO2); 3% dissolved in plasma. "
        "CO2 transport: 70% as bicarbonate (HCO3-) in plasma; 23% bound to haemoglobin (carbamino-Hb); "
        "7% dissolved in plasma. The Bohr effect describes the shift in the O2 dissociation curve: "
        "increased CO2, H+, temperature, and 2,3-DPG shift curve RIGHT (decreased Hb affinity for O2 → more O2 release to tissues).", body))
    e.append(sp(6))
    e.append(box([
        Paragraph("<b>Normal Blood Gas Values:</b>", sub_head),
        Paragraph("pH: 7.35–7.45 | PaO2: 80–100 mmHg | PaCO2: 35–45 mmHg | HCO3-: 22–26 mEq/L | SaO2: >95%", body),
        Paragraph("<b>Respiratory Acidosis:</b> pH ↓, PaCO2 ↑ (hypoventilation, COPD)", body),
        Paragraph("<b>Respiratory Alkalosis:</b> pH ↑, PaCO2 ↓ (hyperventilation, anxiety, altitude)", body),
        Paragraph("<b>Metabolic Acidosis:</b> pH ↓, HCO3- ↓ (DKA, renal failure, diarrhoea)", body),
        Paragraph("<b>Metabolic Alkalosis:</b> pH ↑, HCO3- ↑ (vomiting, diuretics, antacid excess)", body),
    ], bg=TEAL_LIGHT, border=TEAL))
    e.append(pg())
    return e

# ══════════════════════════════════════════════════════════════
# CH 4 – RENAL
# ══════════════════════════════════════════════════════════════
def ch4():
    e = []
    e.append(ChapterHeader("4", "Renal / Urinary System", HexColor("#1A237E")))
    e.append(sp(10))

    e.append(Paragraph("4.1 Anatomy of the Urinary System", sec_head))
    e.append(Paragraph(
        "The urinary system consists of: 2 Kidneys, 2 Ureters, 1 Urinary Bladder, and 1 Urethra. "
        "Kidneys are retroperitoneal, located at T12–L3 vertebral level. Right kidney is slightly lower "
        "than the left (due to the liver). Each kidney weighs about 150 g.", body))

    nephron = [["Part of Nephron", "Location", "Function"],
               ["Bowman's Capsule (Glomerulus)", "Renal cortex", "Filtration of blood; ultrafiltrate formation"],
               ["Proximal Convoluted Tubule (PCT)", "Renal cortex", "Reabsorption of 65% Na+, water, glucose, amino acids, HCO3-"],
               ["Loop of Henle – Descending limb", "Renal medulla", "Water reabsorption (permeable to water, not solutes)"],
               ["Loop of Henle – Ascending limb", "Renal medulla", "NaCl reabsorption (impermeable to water); creates medullary gradient"],
               ["Distal Convoluted Tubule (DCT)", "Renal cortex", "Na+ reabsorption (aldosterone), Ca2+ reabsorption (PTH)"],
               ["Collecting Duct", "Renal medulla", "Water reabsorption (ADH/vasopressin); final urine concentration"]]
    e.append(tbl(nephron, cw=[4.5*cm, 3*cm, 10*cm], hbg=HexColor("#1A237E")))
    e.append(sp(10))

    e.append(Paragraph("4.2 Glomerular Filtration Rate (GFR)", sec_head))
    e.append(Paragraph(
        "GFR is the volume of fluid filtered by the kidneys per minute. Normal GFR ≈ 125 mL/min "
        "(180 L/day). About 99% of filtrate is reabsorbed. Only ~1.5–2 L excreted as urine per day. "
        "GFR is measured by inulin clearance (gold standard) or estimated by serum creatinine (eGFR). "
        "CKD staging is based on GFR:", body))
    ckd = [["CKD Stage", "GFR (mL/min/1.73m²)", "Description"],
           ["Stage 1", "≥ 90 (with kidney damage)", "Normal or high GFR + kidney damage markers"],
           ["Stage 2", "60–89", "Mildly decreased"],
           ["Stage 3a/3b", "30–59", "Moderately decreased"],
           ["Stage 4", "15–29", "Severely decreased"],
           ["Stage 5", "< 15", "Kidney failure (dialysis or transplant needed)"]]
    e.append(tbl(ckd, cw=[3*cm, 5.5*cm, 9*cm], hbg=HexColor("#1A237E")))
    e.append(sp(10))

    e.append(Paragraph("4.3 Normal Urine Characteristics", sec_head))
    urine = [["Property", "Normal Value", "Abnormal Significance"],
             ["Volume/day", "1000–2000 mL", "Oliguria <400 mL; Anuria <100 mL; Polyuria >3000 mL"],
             ["Colour", "Pale yellow (due to urochrome)", "Dark = Concentrated/Jaundice; Red = Haematuria"],
             ["pH", "4.5–8.0 (avg 6.0)", "Alkaline in UTI; Acidic in starvation/acidosis"],
             ["Specific Gravity", "1.002–1.030", "Low = DI/overhydration; High = Dehydration"],
             ["Protein", "< 150 mg/day (nil on dipstick)", "Proteinuria = Nephrotic syndrome, Glomerulonephritis"],
             ["Glucose", "Nil (threshold 180 mg/dL)", "Glycosuria = Diabetes mellitus, Renal glycosuria"],
             ["Ketones", "Nil", "Ketonuria = DKA, starvation, vomiting"],
             ["RBCs", "0–2/HPF", "Haematuria = Stones, UTI, Cancer, Trauma"],
             ["WBCs", "0–5/HPF", "Pyuria = UTI, pyelonephritis"],
             ["Casts", "Occasional hyaline", "Granular casts = AKI; Fatty casts = Nephrotic syndrome"]]
    e.append(tbl(urine, cw=[3.5*cm, 4*cm, 10*cm], hbg=HexColor("#1A237E")))
    e.append(sp(8))
    e.append(box([
        Paragraph("<b>Hormones controlling renal function:</b>", sub_head),
        Paragraph("ADH (Vasopressin) – Posterior pituitary → Water reabsorption in collecting duct → Concentrated urine", body),
        Paragraph("Aldosterone – Adrenal cortex → Na+ reabsorption + K+ excretion in DCT", body),
        Paragraph("ANP (Atrial Natriuretic Peptide) – Atria → Promotes Na+ excretion (natriuresis) → Lowers BP", body),
        Paragraph("Erythropoietin (EPO) – Kidney → Stimulates RBC production in bone marrow", body),
        Paragraph("Renin → Angiotensin I → ACE → Angiotensin II → Vasoconstriction + Aldosterone release → ↑BP", body),
    ], bg=ICE, border=SKY))
    e.append(pg())
    return e

# ══════════════════════════════════════════════════════════════
# CH 5 – DIGESTIVE
# ══════════════════════════════════════════════════════════════
def ch5():
    e = []
    e.append(ChapterHeader("5", "Digestive System & Liver", HexColor("#33691E")))
    e.append(sp(10))

    e.append(Paragraph("5.1 GI Tract – Organs & Functions", sec_head))
    gi = [["Organ", "Key Secretions", "Function"],
          ["Mouth (Salivary glands)", "Salivary amylase (ptyalin), mucus, lingual lipase", "Starch digestion begins; food bolus formation"],
          ["Oesophagus", "Mucus", "Peristalsis transports food to stomach; no digestion"],
          ["Stomach", "HCl (parietal cells), Pepsinogen (chief cells), Intrinsic Factor, Gastrin", "Protein digestion begins; kills bacteria; B12 absorption"],
          ["Small Intestine – Duodenum", "Receives bile + pancreatic juice; secretin, CCK", "Most active digestion; neutralises acid chyme"],
          ["Small Intestine – Jejunum", "Brush border enzymes (maltase, lactase, sucrase)", "Major site of nutrient ABSORPTION"],
          ["Small Intestine – Ileum", "Bile salt reabsorption; Vitamin B12 + intrinsic factor absorption", "Absorption of fat-soluble vitamins, B12, bile salts"],
          ["Large Intestine (Colon)", "Mucus only", "Water and electrolyte absorption; faeces formation"],
          ["Rectum + Anal canal", "Mucus", "Defaecation"]]
    e.append(tbl(gi, cw=[3.5*cm, 5.5*cm, 8.5*cm], hbg=HexColor("#33691E")))
    e.append(sp(10))

    e.append(Paragraph("5.2 Pancreatic Enzymes", sec_head))
    panc = [["Enzyme", "Precursor (Zymogen)", "Substrate", "Activator"],
            ["Trypsin", "Trypsinogen", "Proteins → Peptides", "Enterokinase (duodenum)"],
            ["Chymotrypsin", "Chymotrypsinogen", "Proteins → Peptides", "Trypsin"],
            ["Pancreatic Amylase", "—", "Starch → Maltose", "—"],
            ["Pancreatic Lipase", "—", "Triglycerides → Fatty acids + Glycerol", "Bile salts (emulsify fat)"],
            ["Elastase", "Proelastase", "Elastin and other proteins", "Trypsin"],
            ["Carboxypeptidase", "Procarboxypeptidase", "Proteins → Amino acids (C-terminal)", "Trypsin"]]
    e.append(tbl(panc, cw=[4*cm, 3*cm, 5.5*cm, 5*cm], hbg=HexColor("#33691E")))
    e.append(sp(10))

    e.append(Paragraph("5.3 The Liver – Functions & Clinical Importance", sec_head))
    liver_fn = [
        ("Bile Production", "Bile is produced by hepatocytes (600–1000 mL/day), stored in gallbladder, released into duodenum. "
                            "Bile salts emulsify fats. Bile contains: bile salts, cholesterol, bilirubin, lecithin, electrolytes."),
        ("Metabolism", "Carbohydrate: glycogenesis, glycogenolysis, gluconeogenesis. "
                       "Protein: deamination, urea cycle (converts NH3 to urea). "
                       "Fat: fatty acid oxidation, ketone body synthesis, cholesterol synthesis."),
        ("Detoxification", "Drugs and toxins (Cytochrome P450 system). Alcohol metabolism. "
                           "First-pass metabolism of oral drugs."),
        ("Synthesis", "Plasma proteins: Albumin, fibrinogen, prothrombin, clotting factors (II, VII, IX, X – Vit K dependent). "
                      "Low albumin → oedema (reduced oncotic pressure)."),
        ("Storage", "Glycogen, fat-soluble vitamins (A, D, E, K), vitamin B12, iron (as ferritin)."),
        ("Bilirubin Metabolism", "Haemoglobin → Haem → Biliverdin → Unconjugated bilirubin (bound albumin) → "
                                 "Liver conjugates (glucuronic acid) → Conjugated bilirubin → Bile → Gut → "
                                 "Urobilinogen (some reabsorbed) → Stercobilin (faeces). "
                                 "Jaundice: pre-hepatic (haemolytic), hepatic (liver disease), post-hepatic (obstructive)."),
    ]
    for name, desc in liver_fn:
        e.append(Paragraph(name, sub_head))
        e.append(Paragraph(desc, body))
    e.append(pg())
    return e

# ══════════════════════════════════════════════════════════════
# CH 6 – ENDOCRINE
# ══════════════════════════════════════════════════════════════
def ch6():
    e = []
    e.append(ChapterHeader("6", "Endocrine System", HexColor("#4A0072")))
    e.append(sp(10))

    e.append(Paragraph("6.1 Major Endocrine Glands, Hormones & Functions", sec_head))
    endo = [["Gland", "Hormone", "Function", "Deficiency / Excess"],
            ["Anterior Pituitary\n(Adenohypophysis)", "GH, TSH, ACTH, FSH, LH, Prolactin", "Controls other glands; growth; reproduction", "GH deficiency = dwarfism; GH excess = acromegaly (adults)"],
            ["Posterior Pituitary\n(Neurohypophysis)", "ADH (Vasopressin), Oxytocin", "Water reabsorption; uterine contraction; milk ejection", "ADH deficiency = Diabetes Insipidus"],
            ["Thyroid", "T3, T4 (Triiodothyronine, Thyroxine), Calcitonin", "Basal metabolic rate; growth; CNS development", "Hypothyroid = myxoedema, cretinism (child); Hyperthyroid = Graves' disease"],
            ["Parathyroid (4 glands)", "Parathyroid Hormone (PTH)", "Raises serum Ca2+ (↑bone resorption, ↑renal Ca reabsorption, ↑Vit D activation)", "Hypoparathyroid = Hypocalcaemia, tetany"],
            ["Adrenal Cortex", "Cortisol (glucocorticoid), Aldosterone (mineralocorticoid), Androgens", "Stress response; Na+/K+ balance; sex characteristics", "Addison's (cortisol deficiency); Cushing's (cortisol excess); Conn's (aldosterone excess)"],
            ["Adrenal Medulla", "Adrenaline (Epinephrine), Noradrenaline", "Fight-or-flight: ↑HR, ↑BP, ↑blood glucose, bronchodilation", "Phaeochromocytoma = excess catecholamines"],
            ["Pancreas – Beta cells", "Insulin", "Lowers blood glucose; promotes glycogenesis, lipogenesis, protein synthesis", "Type 1 DM (absent insulin); Type 2 DM (insulin resistance)"],
            ["Pancreas – Alpha cells", "Glucagon", "Raises blood glucose (glycogenolysis, gluconeogenesis)", "Glucagonoma = hyperglycaemia"],
            ["Pineal Gland", "Melatonin", "Regulates circadian rhythm and sleep-wake cycle", "Disrupted in jet lag, shift work"],
            ["Thymus", "Thymosin", "T-lymphocyte maturation (active in childhood, involutes in adults)", "Myasthenia gravis association"]]
    e.append(tbl(endo, cw=[3.5*cm, 4*cm, 5.5*cm, 4.5*cm], hbg=HexColor("#4A0072")))
    e.append(sp(10))

    e.append(Paragraph("6.2 Blood Sugar Regulation", sec_head))
    e.append(box([
        Paragraph("<b>After eating</b> (blood glucose rises) → Insulin secreted → "
                  "Glucose taken into cells; glycogen stored in liver/muscle; lipogenesis → Blood glucose falls.", body),
        Paragraph("<b>Fasting</b> (blood glucose falls) → Glucagon secreted → "
                  "Glycogenolysis + gluconeogenesis in liver → Blood glucose rises.", body),
        Paragraph("<b>Cortisol, GH, Adrenaline</b> are counter-regulatory hormones that raise blood glucose.", body),
        Paragraph("<b>Diabetes Mellitus:</b> Type 1 = autoimmune destruction of beta cells (absolute insulin deficiency). "
                  "Type 2 = insulin resistance + relative insulin deficiency. "
                  "HbA1c ≥ 6.5% = diagnostic for DM.", warn_s),
    ], bg=PURPLE_LT, border=PURPLE))
    e.append(pg())
    return e

# ══════════════════════════════════════════════════════════════
# CH 7 – NERVOUS SYSTEM
# ══════════════════════════════════════════════════════════════
def ch7():
    e = []
    e.append(ChapterHeader("7", "Nervous System & Special Senses", HexColor("#01579B")))
    e.append(sp(10))

    e.append(Paragraph("7.1 Divisions of the Nervous System", sec_head))
    ns = [["Division", "Sub-division", "Components / Role"],
          ["Central Nervous System (CNS)", "Brain", "Cerebrum (thinking, movement, sensation), Cerebellum (coordination, balance), Brainstem (vital centres), Diencephalon (thalamus, hypothalamus)"],
          ["CNS", "Spinal cord", "Reflex arcs; conducts sensory (ascending) and motor (descending) tracts"],
          ["Peripheral Nervous System (PNS)", "Somatic NS", "Voluntary control of skeletal muscle"],
          ["PNS", "Autonomic NS – Sympathetic", "'Fight-or-flight': ↑HR, ↑BP, dilates pupils, bronchodilation, inhibits digestion"],
          ["PNS", "Autonomic NS – Parasympathetic", "'Rest-and-digest': ↓HR, stimulates digestion, constricts pupils, bronchoconstriction"]]
    e.append(tbl(ns, cw=[4.5*cm, 3.5*cm, 9.5*cm], hbg=HexColor("#01579B")))
    e.append(sp(10))

    e.append(Paragraph("7.2 Brain Regions & Functions", sec_head))
    brain = [["Brain Region", "Sub-regions", "Key Functions"],
             ["Cerebrum (Largest)", "Frontal, Parietal, Temporal, Occipital lobes", "Frontal=voluntary movement+personality; Parietal=sensation+spatial awareness; Temporal=hearing+memory+language; Occipital=vision"],
             ["Cerebellum", "Vermis, Hemispheres", "Coordination, balance, fine motor control; Damaged → Ataxia"],
             ["Brainstem", "Midbrain, Pons, Medulla oblongata", "Medulla = Vital centres (HR, BP, breathing, vomiting); Pons = Sleep, REM; Midbrain = Eye movement (CN III, IV)"],
             ["Thalamus", "—", "Relay station for all sensory signals (except smell) to cortex"],
             ["Hypothalamus", "—", "Controls temperature, hunger, thirst, sleep, circadian rhythm; pituitary regulation; linked to emotions"],
             ["Limbic System", "Hippocampus, Amygdala, Cingulate gyrus", "Hippocampus = Memory formation; Amygdala = Emotion, fear; Limbic = Emotional behaviour"]]
    e.append(tbl(brain, cw=[3.5*cm, 4*cm, 10*cm], hbg=HexColor("#01579B")))
    e.append(sp(10))

    e.append(Paragraph("7.3 Cranial Nerves (12 Pairs) – Mnemonic", sec_head))
    e.append(box([
        Paragraph("<b>Mnemonic:</b> 'Oh, Oh, Oh, To Touch And Feel Very Good Velvet, Ah Heaven!'", sub_head),
        Paragraph("I Olfactory – Smell | II Optic – Vision | III Oculomotor – Eye movement (main) | IV Trochlear – Eye movement (SO) | V Trigeminal – Face sensation + chewing | VI Abducens – Eye movement (lateral) | VII Facial – Face expression + taste (ant 2/3 tongue) | VIII Vestibulocochlear – Hearing + Balance | IX Glossopharyngeal – Taste (post 1/3) + swallowing | X Vagus – Parasympathetic to thorax + abdomen | XI Accessory – SCM + trapezius muscle | XII Hypoglossal – Tongue movement", body),
    ], bg=ICE, border=SKY))
    e.append(sp(8))
    e.append(box([
        Paragraph("<b>Blood-Brain Barrier (BBB):</b> Formed by tight junctions between endothelial cells of brain capillaries, reinforced by astrocyte foot processes. "
                  "Allows lipid-soluble substances, O2, CO2, glucose. "
                  "Blocks bacteria and most drugs. "
                  "Broken down in meningitis, trauma, inflammation.", note_s),
    ], bg=AMBER_LT, border=AMBER))
    e.append(pg())
    return e

# ══════════════════════════════════════════════════════════════
# CH 8 – MUSCULOSKELETAL + BLOOD
# ══════════════════════════════════════════════════════════════
def ch8():
    e = []
    e.append(ChapterHeader("8", "Musculoskeletal System & Blood", HexColor("#BF360C")))
    e.append(sp(10))

    e.append(Paragraph("8.1 Skeletal System – Key Facts", sec_head))
    skel = [["Fact", "Detail"],
            ["Total bones in adults", "206 bones"],
            ["Total bones in infants", "~270–300 (fuse during development)"],
            ["Longest bone", "Femur (thigh bone)"],
            ["Smallest bone", "Stapes (ear ossicle)"],
            ["Hardest bone", "Petrous part of temporal bone"],
            ["Largest joint", "Knee (tibiofemoral) joint"],
            ["Haematopoiesis (blood cell formation)", "Red bone marrow (sternum, ileum, vertebrae, ribs, proximal femur)"],
            ["Bone mineral content", "Hydroxyapatite crystals: Ca10(PO4)6(OH)2"],
            ["Osteoblasts", "Bone-forming cells"],
            ["Osteoclasts", "Bone-resorbing cells (activated by PTH)"],
            ["Vitamin D + Calcium + PTH", "Regulate bone metabolism"],
            ["Fracture healing", "Haematoma → Soft callus → Hard callus → Remodelling"]]
    e.append(tbl(skel, cw=[6*cm, 11.5*cm], hbg=HexColor("#BF360C")))
    e.append(sp(10))

    e.append(Paragraph("8.2 Muscle Types Comparison", sec_head))
    muscle = [["Feature", "Skeletal Muscle", "Cardiac Muscle", "Smooth Muscle"],
              ["Control", "Voluntary", "Involuntary (automatic)", "Involuntary"],
              ["Appearance", "Striated", "Striated", "Non-striated"],
              ["Nuclei", "Multinucleated (peripheral)", "1–2 nuclei (central)", "Single nucleus (central)"],
              ["Location", "Attached to bones", "Heart wall only", "Visceral organs, blood vessels"],
              ["Regeneration", "Limited (satellite cells)", "Minimal", "Good (stem cells)"],
              ["Intercalated discs", "Absent", "Present", "Absent"],
              ["Gap junctions (Nexus)", "Absent", "Present (syncytium)", "Present"]]
    e.append(tbl(muscle, cw=[4.5*cm, 4*cm, 4*cm, 5*cm], hbg=HexColor("#BF360C")))
    e.append(sp(10))

    e.append(Paragraph("8.3 Blood – Complete Summary", sec_head))
    e.append(Paragraph(
        "Blood volume in adults ≈ 5–6 L (70–80 mL/kg body weight). "
        "Blood is composed of Plasma (55%) + Formed elements (45%).", body))
    blood = [["Component", "Normal Value", "Produced In", "Function / Key Fact"],
             ["RBC (Erythrocytes)", "Male: 4.5–5.5 million/µL; Female: 3.8–5.0 million/µL", "Bone marrow (EPO-stimulated)", "O2 & CO2 transport via haemoglobin; no nucleus; lifespan ~120 days"],
             ["WBC (Leukocytes)", "4,000–11,000/µL", "Bone marrow + lymphoid tissue", "Immune defence; neutrophils most common (60–70%)"],
             ["Platelets (Thrombocytes)", "1.5–4 lakh/µL", "Bone marrow (megakaryocytes)", "Haemostasis (primary platelet plug); lifespan ~10 days"],
             ["Haemoglobin (Hb)", "Male: 13–17 g/dL; Female: 12–15 g/dL", "In RBCs", "O2 carrier; 4 haem + 4 globin chains; HbA = α2β2 (adult)"],
             ["Plasma (55%)", "Water 90–92%, Proteins 7–8%, Others", "Liver (proteins)", "Transport medium; albumin (oncotic pressure), globulin (antibodies), fibrinogen (clotting)"],
             ["Serum", "Plasma minus fibrinogen + clotting factors", "—", "Used in serology/biochemistry tests (red/gold tube)"]]
    e.append(tbl(blood, cw=[3.5*cm, 4*cm, 3.5*cm, 6.5*cm], hbg=HexColor("#BF360C")))
    e.append(sp(8))

    e.append(Paragraph("8.4 WBC Differential Count", sec_head))
    wbc = [["WBC Type", "Normal %", "Function", "Elevated In"],
           ["Neutrophils", "60–70%", "First responders; phagocytosis of bacteria", "Bacterial infection, inflammation"],
           ["Lymphocytes", "20–30%", "T cells (cellular immunity), B cells (humoral antibody)", "Viral infection, CLL, lymphoma"],
           ["Monocytes", "2–8%", "Large phagocytes; become macrophages in tissue", "Chronic infections, monocytic leukaemia"],
           ["Eosinophils", "1–4%", "Allergy/parasitic reactions; phagocytosis of antigen-antibody complexes", "Allergy, asthma, parasitic infections"],
           ["Basophils", "0–1%", "Release histamine and heparin; involved in allergy (IgE-mediated)", "Allergic reactions, CML"]]
    e.append(tbl(wbc, cw=[3*cm, 2*cm, 6*cm, 6.5*cm], hbg=HexColor("#BF360C")))
    e.append(pg())
    return e

# ══════════════════════════════════════════════════════════════
# CH 9 – REPRODUCTIVE + IMMUNE
# ══════════════════════════════════════════════════════════════
def ch9():
    e = []
    e.append(ChapterHeader("9", "Reproductive & Immune Systems", HexColor("#880E4F")))
    e.append(sp(10))

    e.append(Paragraph("9.1 Male Reproductive System", sec_head))
    male_rep = [["Structure", "Function"],
                ["Testes", "Produce spermatozoa (spermatogenesis) and testosterone (Leydig cells)"],
                ["Seminiferous tubules", "Site of spermatogenesis; Sertoli cells nourish developing sperm"],
                ["Epididymis", "Sperm maturation and storage (~3 weeks)"],
                ["Vas deferens", "Transports sperm from epididymis to ejaculatory duct"],
                ["Seminal vesicles", "Secrete fructose-rich fluid (60% of semen volume); prostaglandins"],
                ["Prostate gland", "Secretes prostatic fluid (alkaline); PSA enzyme; 30% semen volume"],
                ["Bulbourethral glands (Cowper's)", "Pre-ejaculatory mucus; neutralises urethral acidity"]]
    e.append(tbl(male_rep, cw=[5*cm, 12.5*cm], hbg=HexColor("#880E4F")))
    e.append(sp(10))

    e.append(Paragraph("9.2 Female Reproductive System & Menstrual Cycle", sec_head))
    fem_rep = [["Phase", "Days (28-day cycle)", "Dominant Hormone", "Key Events"],
               ["Menstrual phase", "Days 1–5", "All low", "Shedding of endometrium (menses)"],
               ["Follicular (Proliferative) phase", "Days 6–13", "Oestrogen (rising)", "FSH stimulates follicle growth; oestrogen thickens endometrium"],
               ["Ovulation", "Day 14", "LH surge", "LH surge triggers release of mature ovum from dominant follicle"],
               ["Luteal (Secretory) phase", "Days 15–28", "Progesterone (dominant)", "Corpus luteum secretes progesterone; prepares endometrium for implantation"]]
    e.append(tbl(fem_rep, cw=[4*cm, 3*cm, 4*cm, 6.5*cm], hbg=HexColor("#880E4F")))
    e.append(sp(8))
    e.append(box([
        Paragraph("<b>Key hormone facts:</b>", sub_head),
        Paragraph("FSH = Follicle Stimulating Hormone (from anterior pituitary) | LH = Luteinising Hormone (from anterior pituitary)", body),
        Paragraph("Oestrogen = produced by ovarian follicle | Progesterone = produced by corpus luteum", body),
        Paragraph("hCG (Human Chorionic Gonadotropin) = first hormone of pregnancy; basis of pregnancy tests", body),
    ], bg=PURPLE_LT, border=PURPLE))
    e.append(sp(10))

    e.append(Paragraph("9.3 Immune System – Overview", sec_head))
    immune = [["Type", "Components", "Key Features"],
              ["Innate Immunity (Non-specific)", "Skin, mucus, cilia, stomach acid, phagocytes (neutrophils, macrophages), NK cells, complement, interferons", "First line of defence; fast (immediate); no memory; non-specific"],
              ["Adaptive Immunity (Specific)", "B lymphocytes → Plasma cells → Antibodies (Humoral immunity). T lymphocytes → Cellular immunity (kill infected cells, activate macrophages)", "Slow (days–weeks); specific; has MEMORY; long-lasting"],
              ["Active Immunity", "Produced by body after infection or vaccination", "Long-lasting; slower initial response; memory cells formed"],
              ["Passive Immunity", "Antibodies transferred (breast milk = IgA; maternal IgG across placenta; antitoxin injection)", "Immediate protection; short-lived; no memory"]]
    e.append(tbl(immune, cw=[4*cm, 6.5*cm, 7*cm], hbg=HexColor("#880E4F")))
    e.append(sp(8))

    e.append(Paragraph("9.4 Antibody (Immunoglobulin) Classes", sec_head))
    ig = [["Ig Class", "% of Serum Ig", "Key Function / Location"],
          ["IgG", "75–80% (most abundant)", "Main serum antibody; crosses placenta (passive immunity to foetus); secondary immune response"],
          ["IgA", "10–15%", "Secretory antibody (breast milk, saliva, tears, mucosa); protects mucosal surfaces"],
          ["IgM", "5–10%", "First antibody produced in primary response; pentameric (5 units); best at complement activation; ABO antibodies are IgM"],
          ["IgE", "< 0.001%", "Binds mast cells and basophils; mediates type I hypersensitivity (allergy, anaphylaxis, asthma); elevated in parasitic infections"],
          ["IgD", "< 1%", "On naive B cell surface; antigen receptor; role in B cell activation"]]
    e.append(tbl(ig, cw=[2.5*cm, 3.5*cm, 11.5*cm], hbg=HexColor("#880E4F")))
    e.append(pg())
    return e

# ══════════════════════════════════════════════════════════════
# CH 10 – QUICK REFERENCE + MCQ MOCK TEST
# ══════════════════════════════════════════════════════════════
def ch10():
    e = []
    e.append(ChapterHeader("10", "Quick-Reference Tables & 50-Question Mock Test", NAVY))
    e.append(sp(10))

    e.append(SectionBand("QUICK-REFERENCE: Master Value Table", ROYAL))
    e.append(sp(6))
    master = [["Parameter", "Normal Value", "High = ", "Low = "],
              ["Hemoglobin (M)", "13–17 g/dL", "Polycythaemia", "Anaemia"],
              ["Hemoglobin (F)", "12–15 g/dL", "Polycythaemia", "Anaemia"],
              ["RBC (M)", "4.5–5.5 M/µL", "Polycythaemia vera", "Anaemia"],
              ["WBC", "4,000–11,000/µL", "Leukocytosis (infection)", "Leukopenia (viral, chemo)"],
              ["Platelets", "1.5–4 lakh/µL", "Thrombocytosis", "Thrombocytopenia (bleeding)"],
              ["PCV (M)", "40–54%", "Dehydration/Polycythaemia", "Anaemia/Overhydration"],
              ["Blood pH", "7.35–7.45", "Alkalosis (>7.45)", "Acidosis (<7.35)"],
              ["PaO2", "80–100 mmHg", "Hyperoxia", "Hypoxia (<80)"],
              ["PaCO2", "35–45 mmHg", "Hypercapnia (hypoventilation)", "Hypocapnia (hyperventilation)"],
              ["HCO3-", "22–26 mEq/L", "Metabolic alkalosis", "Metabolic acidosis"],
              ["Fasting glucose", "70–100 mg/dL", "Diabetes (>126)", "Hypoglycaemia (<70)"],
              ["Serum Creatinine (M)", "0.7–1.2 mg/dL", "Renal failure", "Muscle wasting"],
              ["BUN", "7–20 mg/dL", "Renal failure / dehydration", "Liver failure, malnutrition"],
              ["Serum Albumin", "3.5–5.0 g/dL", "Dehydration", "Cirrhosis / Malnutrition"],
              ["Total Bilirubin", "0.2–1.2 mg/dL", "Jaundice (>1.2)", "—"],
              ["Serum Na+", "135–145 mEq/L", "Hypernatraemia", "Hyponatraemia (seizures)"],
              ["Serum K+", "3.5–5.0 mEq/L", "Hyperkalaemia (arrhythmia)", "Hypokalaemia (weakness)"],
              ["Serum Ca2+", "8.5–10.5 mg/dL", "Hypercalcaemia", "Hypocalcaemia (tetany)"],
              ["ESR (M, Westergren)", "0–15 mm/hr", "Inflammation/infection", "—"],
              ["GFR", "≈ 125 mL/min", "—", "CKD (<60 for >3 months)"],
              ["Vital Capacity", "≈ 4600 mL", "—", "Restrictive lung disease"],
              ["Pulse rate", "60–100/min", "Tachycardia", "Bradycardia"],
              ["BP", "120/80 mmHg", "Hypertension (>140/90)", "Hypotension (<90/60)"],
              ["Body temperature", "37°C / 98.6°F", "Fever (>38°C)", "Hypothermia (<35°C)"]]
    e.append(tbl(master, cw=[4.5*cm, 3*cm, 4.5*cm, 5.5*cm], hbg=NAVY))
    e.append(sp(10))

    e.append(SectionBand("50-QUESTION MOCK TEST – Human Anatomy & Physiology", RED))
    e.append(sp(6))
    e.append(box([Paragraph(
        "<b>Instructions:</b> 50 MCQs | Represents the Anatomy & Physiology section | "
        "Time allowed: ~22 minutes | No Negative Marking | Correct answers marked with ✓", warn_s)],
        bg=RED_LIGHT, border=RED))
    e.append(sp(8))

    mcqs = [
        ("1", "The functional unit of the kidney is:", ["A) Alveolus", "B) Nephron ✓", "C) Villus", "D) Acinus"]),
        ("2", "Which chamber pumps oxygenated blood to the body?", ["A) Right atrium", "B) Left atrium", "C) Right ventricle", "D) Left ventricle ✓"]),
        ("3", "Normal adult blood pH:", ["A) 6.8–7.0", "B) 7.2–7.35", "C) 7.35–7.45 ✓", "D) 7.5–7.8"]),
        ("4", "The pacemaker of the heart is:", ["A) AV node", "B) Bundle of His", "C) SA node ✓", "D) Purkinje fibres"]),
        ("5", "Site of gas exchange in the lungs:", ["A) Bronchi", "B) Trachea", "C) Bronchioles", "D) Alveoli ✓"]),
        ("6", "Which organ produces bile?", ["A) Gallbladder", "B) Pancreas", "C) Liver ✓", "D) Spleen"]),
        ("7", "Normal fasting blood glucose:", ["A) 40–60 mg/dL", "B) 70–100 mg/dL ✓", "C) 120–150 mg/dL", "D) 160–200 mg/dL"]),
        ("8", "Hypothalamus regulates:", ["A) Vision", "B) Balance", "C) Body temperature ✓", "D) Hearing"]),
        ("9", "Hormone responsible for 'fight-or-flight':", ["A) Insulin", "B) Cortisol", "C) Adrenaline ✓", "D) Glucagon"]),
        ("10", "Normal hemoglobin in adult males:", ["A) 10–12 g/dL", "B) 12–14 g/dL", "C) 13–17 g/dL ✓", "D) 18–22 g/dL"]),
        ("11", "Which enzyme digests starch in the mouth?", ["A) Pepsin", "B) Lipase", "C) Salivary amylase ✓", "D) Trypsin"]),
        ("12", "The largest bone in the human body:", ["A) Humerus", "B) Femur ✓", "C) Tibia", "D) Radius"]),
        ("13", "Smallest bone in the human body:", ["A) Malleus", "B) Incus", "C) Stapes ✓", "D) Cochlea"]),
        ("14", "Total number of bones in adult human body:", ["A) 178", "B) 200", "C) 206 ✓", "D) 220"]),
        ("15", "ADH acts on which part of the nephron?", ["A) PCT", "B) Loop of Henle", "C) DCT", "D) Collecting duct ✓"]),
        ("16", "Secretory IgA is found in:", ["A) Blood serum", "B) Body secretions (milk, saliva, tears) ✓", "C) Bone marrow", "D) CSF"]),
        ("17", "Insulin is produced by which cells?", ["A) Alpha cells of pancreas", "B) Beta cells of pancreas ✓", "C) Delta cells of pancreas", "D) Acinar cells"]),
        ("18", "Normal platelet count:", ["A) 50,000–1,00,000/µL", "B) 1,50,000–4,00,000/µL ✓", "C) 5,00,000–7,00,000/µL", "D) 10,000–50,000/µL"]),
        ("19", "Most abundant plasma protein:", ["A) Globulin", "B) Fibrinogen", "C) Albumin ✓", "D) Prothrombin"]),
        ("20", "Which part of the brain controls coordination and balance?", ["A) Cerebrum", "B) Thalamus", "C) Hypothalamus", "D) Cerebellum ✓"]),
        ("21", "Type I pneumocytes:", ["A) Produce surfactant", "B) Cover 95% of alveolar surface ✓", "C) Are cuboidal in shape", "D) Present in bronchi"]),
        ("22", "Which hormone is deficient in Diabetes Insipidus?", ["A) Insulin", "B) ADH ✓", "C) Aldosterone", "D) Cortisol"]),
        ("23", "Tidal Volume (normal adult):", ["A) 150 mL", "B) 300 mL", "C) 500 mL ✓", "D) 1000 mL"]),
        ("24", "Site of vitamin B12 absorption:", ["A) Duodenum", "B) Jejunum", "C) Ileum ✓", "D) Colon"]),
        ("25", "Normal WBC count:", ["A) 1,000–3,000/µL", "B) 4,000–11,000/µL ✓", "C) 12,000–15,000/µL", "D) 20,000–30,000/µL"]),
        ("26", "Haematopoiesis in adults occurs in:", ["A) Liver", "B) Spleen", "C) Yellow bone marrow", "D) Red bone marrow ✓"]),
        ("27", "PTH (Parathyroid Hormone) causes:", ["A) ↓ blood calcium", "B) ↑ blood calcium ✓", "C) ↓ bone resorption", "D) ↑ urinary calcium loss"]),
        ("28", "The QRS complex on ECG represents:", ["A) Atrial depolarisation", "B) Atrial repolarisation", "C) Ventricular depolarisation ✓", "D) Ventricular repolarisation"]),
        ("29", "Most common type of WBC:", ["A) Lymphocytes", "B) Monocytes", "C) Neutrophils ✓", "D) Eosinophils"]),
        ("30", "Surfactant is produced by:", ["A) Type I pneumocytes", "B) Type II pneumocytes ✓", "C) Alveolar macrophages", "D) Club cells"]),
        ("31", "The blood-brain barrier is primarily formed by:", ["A) Neurons", "B) Microglia", "C) Astrocytes ✓", "D) Oligodendrocytes"]),
        ("32", "IgE is involved in:", ["A) Passive immunity", "B) ABO blood group reaction", "C) Type I hypersensitivity (allergy) ✓", "D) Complement activation"]),
        ("33", "Which hormone triggers ovulation?", ["A) FSH", "B) Oestrogen", "C) LH surge ✓", "D) Progesterone"]),
        ("34", "Liver stores which vitamins?", ["A) All water-soluble vitamins", "B) Vitamins A, D, E, K and B12 ✓", "C) Vitamin C only", "D) Vitamins B1 and B2"]),
        ("35", "Normal urine output per day:", ["A) 500–800 mL", "B) 1000–2000 mL ✓", "C) 3000–4000 mL", "D) 200–400 mL"]),
        ("36", "Which antibody crosses the placenta?", ["A) IgA", "B) IgM", "C) IgG ✓", "D) IgE"]),
        ("37", "The Bohr effect states: increased CO2/H+ causes:", ["A) Increased Hb–O2 affinity (curve shifts left)", "B) Decreased Hb–O2 affinity (curve shifts right) ✓", "C) No change in O2 delivery", "D) Decreased CO2 production"]),
        ("38", "GFR is normally approximately:", ["A) 50 mL/min", "B) 80 mL/min", "C) 125 mL/min ✓", "D) 200 mL/min"]),
        ("39", "Cardiac muscle has which unique feature?", ["A) Voluntary control", "B) Multi-nucleated", "C) Intercalated discs ✓", "D) Non-striated"]),
        ("40", "Aldosterone acts on which part of the nephron?", ["A) PCT", "B) Loop of Henle", "C) DCT and collecting duct ✓", "D) Bowman's capsule"]),
        ("41", "The T wave on ECG represents:", ["A) Atrial depolarisation", "B) Ventricular depolarisation", "C) Ventricular repolarisation ✓", "D) SA node firing"]),
        ("42", "Heparin is produced by:", ["A) Kupffer cells", "B) Mast cells ✓", "C) Plasma cells", "D) Chief cells"]),
        ("43", "Normal respiratory rate in adults:", ["A) 5–8/min", "B) 12–20/min ✓", "C) 25–35/min", "D) 40–50/min"]),
        ("44", "The right lung has how many lobes?", ["A) 2", "B) 3 ✓", "C) 4", "D) 5"]),
        ("45", "Intrinsic factor required for absorption of:", ["A) Vitamin C", "B) Iron", "C) Folate", "D) Vitamin B12 ✓"]),
        ("46", "Which is the first antibody produced in primary immune response?", ["A) IgG", "B) IgA", "C) IgM ✓", "D) IgE"]),
        ("47", "Blood volume in an average adult:", ["A) 2–3 litres", "B) 5–6 litres ✓", "C) 8–9 litres", "D) 10–12 litres"]),
        ("48", "The 12th cranial nerve (Hypoglossal) controls:", ["A) Eye movement", "B) Swallowing", "C) Tongue movement ✓", "D) Hearing"]),
        ("49", "Which cells in the testes produce testosterone?", ["A) Sertoli cells", "B) Leydig cells ✓", "C) Spermatogonia", "D) Sustentacular cells"]),
        ("50", "Normal serum potassium (K+):", ["A) 1.5–2.5 mEq/L", "B) 3.5–5.0 mEq/L ✓", "C) 6.0–8.0 mEq/L", "D) 9.0–11.0 mEq/L"]),
    ]

    for qno, qtext, opts in mcqs:
        e.append(Paragraph(f"<b>Q{qno}.</b>  {qtext}", mcq_q))
        row1 = Table([[Paragraph(opts[0], mcq_a), Paragraph(opts[1], mcq_ans if "✓" in opts[1] else mcq_a)]],
                     colWidths=[(W-2*MARGIN)/2]*2)
        row2 = Table([[Paragraph(opts[2], mcq_ans if "✓" in opts[2] else mcq_a), Paragraph(opts[3], mcq_ans if "✓" in opts[3] else mcq_a)]],
                     colWidths=[(W-2*MARGIN)/2]*2)
        for r in [row1, row2]:
            r.setStyle(TableStyle([
                ("TOPPADDING", (0,0), (-1,-1), 0),
                ("BOTTOMPADDING", (0,0), (-1,-1), 1),
                ("LEFTPADDING", (0,0), (-1,-1), 8),
            ]))
        e.append(row1); e.append(row2); e.append(sp(3))

    e.append(sp(10))
    e.append(box([
        Paragraph("<b>Correct answers are highlighted in green (✓) in each question above.</b>", key_s),
        Paragraph("Target: 18+/25 in this section during the actual exam. Aim for 22+ for strong selection.", body),
    ], bg=GREEN_LT, border=GREEN))
    e.append(sp(16))
    e.append(HRFlowable(width="100%", thickness=1, color=GREY_MID))
    e.append(sp(6))
    e.append(Paragraph(
        "ASI Lab Technician 2026 – Human Anatomy & Physiology Study Guide | CISF & BSF Paramedical Exam",
        S("FT", fontName="Helvetica-Oblique", fontSize=8, textColor=GREY_MID, alignment=TA_CENTER)))
    return e

# ══════════════════════════════════════════════════════════════
# PAGE FOOTER
# ══════════════════════════════════════════════════════════════
def on_later_pages(canvas, doc):
    canvas.saveState()
    canvas.setFont("Helvetica", 7.5)
    canvas.setFillColor(GREY_MID)
    canvas.drawString(MARGIN, 0.6*cm, "ASI Lab Technician 2026 | Human Anatomy & Physiology")
    canvas.drawRightString(W - MARGIN, 0.6*cm, f"Page {doc.page}")
    canvas.setStrokeColor(HexColor("#B0BEC5"))
    canvas.setLineWidth(0.5)
    canvas.line(MARGIN, 0.85*cm, W - MARGIN, 0.85*cm)
    canvas.restoreState()

def build():
    doc = SimpleDocTemplate(
        OUTPUT, pagesize=A4,
        leftMargin=MARGIN, rightMargin=MARGIN,
        topMargin=MARGIN, bottomMargin=1.5*cm,
        title="ASI Lab Technician – Human Anatomy & Physiology Study Guide 2026",
        author="Orris",
        subject="CISF BSF ASI Lab Technician Anatomy Physiology Guide",
    )
    story = []
    story += cover()
    story += ch1()
    story += ch2()
    story += ch3()
    story += ch4()
    story += ch5()
    story += ch6()
    story += ch7()
    story += ch8()
    story += ch9()
    story += ch10()
    doc.build(story, onFirstPage=lambda c, d: None, onLaterPages=on_later_pages)
    print(f"PDF created: {OUTPUT}")

build()
Running Command

cd /tmp/workspace/asi-lab-tech-guide && python build_anatomy.py 2>&1

Running Command

ls -lh /tmp/workspace/asi-lab-tech-guide/

Your focused study guide is ready! Download it here:

ASI Human Anatomy Physiology Guide 2026

PDF Document · PDF


What's Inside This Guide

This PDF covers only Human Anatomy & Physiology — the full 25-mark section of the ASI Lab Technician exam — with deep detail across 10 chapters:
ChapterTopics Covered
Ch 1Cell biology, organelles & their functions, 4 tissue types
Ch 2Heart structure, 4 chambers, cardiac conduction (SA→AV→Purkinje), ECG waves, blood pressure, blood vessels
Ch 3Respiratory tract anatomy, lung volumes (TV, VC, TLC, FRC), gas exchange, blood gas values, acid-base disorders
Ch 4Nephron anatomy step-by-step, GFR, CKD staging, urine characteristics, hormones (ADH, Aldosterone, RAAS)
Ch 5GI tract organs & secretions, all pancreatic enzymes, liver functions + bilirubin metabolism
Ch 6All endocrine glands, hormones & diseases (Addison's, Cushing's, DM, DI), blood sugar regulation
Ch 7CNS divisions, all 4 brain regions + functions, 12 cranial nerves with mnemonic, blood-brain barrier
Ch 8206 bones, muscle type comparisons, blood components & CBC values, WBC differential with %
Ch 9Male & female reproductive anatomy, menstrual cycle phases, hormone sequence, immune system, 5 Ig classes
Ch 10Master reference value table (25+ parameters) + 50-question mock test with answers highlighted in green

The tables you create some arts are collapsing in it

Writing File

~/asi-lab-tech-guide/build_anatomy_v2.py

"""
ASI Lab Technician 2026 – Human Anatomy & Physiology Study Guide
Fixed version: all table cells use Paragraph (word-wrap), column widths sum
exactly to usable width, no plain strings in table data rows.
"""

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    PageBreak, HRFlowable, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.lib.colors import HexColor

# ── Page geometry ──────────────────────────────────────────────
A4_W, A4_H = A4          # 595.27 x 841.89 pts
LEFT = RIGHT = 1.8 * cm
TOP  = BOTTOM = 1.8 * cm
TW = A4_W - LEFT - RIGHT  # usable text width ≈ 557.5 pts
OUTPUT = "/tmp/workspace/asi-lab-tech-guide/ASI_Human_Anatomy_Physiology_Guide_2026_v2.pdf"

# ── Colour palette ─────────────────────────────────────────────
NAVY    = HexColor("#0D1B4B")
ROYAL   = HexColor("#1565C0")
SKY     = HexColor("#1E88E5")
ICE     = HexColor("#E3F2FD")
TEAL    = HexColor("#00796B")
TEAL_LT = HexColor("#E0F2F1")
RED     = HexColor("#B71C1C")
RED_LT  = HexColor("#FFEBEE")
AMBER   = HexColor("#E65100")
AMB_LT  = HexColor("#FFF3E0")
GREEN   = HexColor("#1B5E20")
GRN_LT  = HexColor("#E8F5E9")
PURPLE  = HexColor("#4A148C")
PUR_LT  = HexColor("#F3E5F5")
GREY    = HexColor("#37474F")
GREY_M  = HexColor("#546E7A")
WHITE   = colors.white

# ── Style factory ──────────────────────────────────────────────
def S(name, **kw):
    return ParagraphStyle(name, **kw)

# Base cell styles (all word-wrap friendly)
TH = S("TH", fontName="Helvetica-Bold",  fontSize=8.5, textColor=WHITE,
       leading=12, wordWrap="LTR", spaceAfter=0, spaceBefore=0)
TD = S("TD", fontName="Helvetica",       fontSize=8.5, textColor=GREY,
       leading=12, wordWrap="LTR", spaceAfter=0, spaceBefore=0)
TDB = S("TDB", fontName="Helvetica-Bold", fontSize=8.5, textColor=GREY,
        leading=12, wordWrap="LTR", spaceAfter=0, spaceBefore=0)

# Document-level styles
cov_ttl  = S("CT",  fontName="Helvetica-Bold",   fontSize=30, textColor=WHITE, alignment=TA_CENTER, leading=38, spaceAfter=8)
cov_sub  = S("CS",  fontName="Helvetica",         fontSize=13, textColor=HexColor("#BBDEFB"), alignment=TA_CENTER, leading=20, spaceAfter=6)
cov_bdg  = S("CB",  fontName="Helvetica-Bold",    fontSize=11, textColor=HexColor("#FFD54F"), alignment=TA_CENTER, spaceAfter=4)
sec_h    = S("SH",  fontName="Helvetica-Bold",    fontSize=12, textColor=NAVY, spaceBefore=12, spaceAfter=5, leading=16)
sub_h    = S("SuH", fontName="Helvetica-Bold",    fontSize=10.5, textColor=ROYAL, spaceBefore=9, spaceAfter=3, leading=14)
body     = S("Bo",  fontName="Helvetica",          fontSize=9.5, textColor=GREY, leading=14, spaceAfter=4, alignment=TA_JUSTIFY, wordWrap="LTR")
bul      = S("Bu",  fontName="Helvetica",          fontSize=9.5, textColor=GREY, leading=13, spaceAfter=3, leftIndent=14, wordWrap="LTR")
key      = S("Ke",  fontName="Helvetica-Bold",     fontSize=9.5, textColor=GREEN, leading=13, spaceAfter=3, leftIndent=14, wordWrap="LTR")
note     = S("No",  fontName="Helvetica-Oblique",  fontSize=9,   textColor=PURPLE, leading=13, spaceAfter=4, leftIndent=8, wordWrap="LTR")
warn     = S("Wa",  fontName="Helvetica-Bold",     fontSize=9.5, textColor=RED, leading=13, spaceAfter=3, leftIndent=8, wordWrap="LTR")
mcq_q    = S("MQ",  fontName="Helvetica-Bold",     fontSize=9.5, textColor=NAVY, leading=14, spaceAfter=2, spaceBefore=5, wordWrap="LTR")
mcq_ok   = S("MOK", fontName="Helvetica-Bold",     fontSize=9.5, textColor=GREEN, leading=13, spaceAfter=1, leftIndent=10, wordWrap="LTR")
mcq_no   = S("MNO", fontName="Helvetica",          fontSize=9.5, textColor=GREY, leading=13, spaceAfter=1, leftIndent=10, wordWrap="LTR")
toc_s    = S("TOC", fontName="Helvetica",          fontSize=10,  textColor=GREY, leading=20, leftIndent=12, wordWrap="LTR")

# ── Helpers ────────────────────────────────────────────────────
def sp(n=6):  return Spacer(1, n)
def pg():     return PageBreak()
def bu(t):    return Paragraph(f"&#x2022;  {t}", bul)
def kl(t):    return Paragraph(f"&#x2714;  {t}", key)
def p(t, st=body): return Paragraph(t, st)

def P(text, bold=False, italic=False):
    """Shorthand for a table cell Paragraph."""
    st = TDB if bold else TD
    if italic:
        return Paragraph(f"<i>{text}</i>", TD)
    return Paragraph(text, st)

def PH(text):
    """Header cell Paragraph."""
    return Paragraph(text, TH)


def tbl(rows, cw, hbg=NAVY, alt=ICE):
    """
    Build a Table from `rows` (list of lists).
    - `rows[0]` = header row (strings → PH wrapping)
    - rest      = data rows (strings → P wrapping)
    - `cw`      = list of column widths (MUST sum to TW)
    The function converts any bare string to a Paragraph so
    word-wrap always works.
    """
    assert abs(sum(cw) - TW) < 2, f"Column widths {sum(cw):.1f} != TW {TW:.1f}"

    converted = []
    for r_idx, row in enumerate(rows):
        new_row = []
        for cell in row:
            if isinstance(cell, str):
                new_row.append(PH(cell) if r_idx == 0 else P(cell))
            else:
                new_row.append(cell)
        converted.append(new_row)

    t = Table(converted, colWidths=cw, repeatRows=1)
    t.setStyle(TableStyle([
        # Header
        ("BACKGROUND",    (0, 0), (-1, 0),  hbg),
        ("TEXTCOLOR",     (0, 0), (-1, 0),  WHITE),
        # Alternating rows
        ("ROWBACKGROUNDS",(0, 1), (-1, -1), [WHITE, alt]),
        # Grid
        ("GRID",          (0, 0), (-1, -1), 0.5, HexColor("#B0BEC5")),
        # Padding (generous so text never clips)
        ("TOPPADDING",    (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
        ("LEFTPADDING",   (0, 0), (-1, -1), 6),
        ("RIGHTPADDING",  (0, 0), (-1, -1), 6),
        # Vertical align
        ("VALIGN",        (0, 0), (-1, -1), "TOP"),
    ]))
    return t


def box(items, bg=ICE, border=SKY):
    """Coloured info/warning box."""
    data = [[item] for item in items]
    t = Table(data, colWidths=[TW])
    t.setStyle(TableStyle([
        ("BACKGROUND",   (0, 0), (-1, -1), bg),
        ("BOX",          (0, 0), (-1, -1), 1.2, border),
        ("TOPPADDING",   (0, 0), (-1, -1), 7),
        ("BOTTOMPADDING",(0, 0), (-1, -1), 7),
        ("LEFTPADDING",  (0, 0), (-1, -1), 10),
        ("RIGHTPADDING", (0, 0), (-1, -1), 10),
    ]))
    return t


class ChapterHeader(Flowable):
    def __init__(self, num, title, color=NAVY, h=1.25 * cm):
        Flowable.__init__(self)
        self.num = num; self.title = title
        self.color = color; self.bh = h

    def draw(self):
        c = self.canv
        c.setFillColor(self.color)
        c.roundRect(0, 0, self.width, self.bh, 8, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont("Helvetica-Bold", 13)
        label = f"Chapter {self.num}:  {self.title}"
        c.drawString(14, self.bh * 0.28, label)

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


class SectionBand(Flowable):
    def __init__(self, title, color=SKY, h=0.65 * cm):
        Flowable.__init__(self); self.title = title
        self.color = color; self.bh = h

    def draw(self):
        c = self.canv
        c.setFillColor(self.color)
        c.roundRect(0, 0, self.width, self.bh, 5, fill=1, stroke=0)
        c.setFillColor(WHITE); c.setFont("Helvetica-Bold", 10)
        c.drawString(10, self.bh * 0.22, self.title)

    def wrap(self, aw, ah):
        self.width = aw; return aw, self.bh


# ══════════════════════════════════════════════════════════════
# COVER
# ══════════════════════════════════════════════════════════════
def cover():
    e = []
    e.append(sp(20))

    banner_rows = [
        [p("CISF / BSF  |  ASI Lab Technician 2026", cov_bdg)],
        [p("Human Anatomy & Physiology", cov_ttl)],
        [p("In-Depth Study Guide", cov_sub)],
        [sp(4)],
        [p("25 Questions · 25 Marks · Section B of Written Exam", cov_bdg)],
    ]
    bt = Table(banner_rows, colWidths=[TW])
    bt.setStyle(TableStyle([
        ("BACKGROUND",    (0, 0), (-1, -1), NAVY),
        ("TOPPADDING",    (0, 0), (-1, -1), 6),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 6),
        ("LEFTPADDING",   (0, 0), (-1, -1), 18),
        ("RIGHTPADDING",  (0, 0), (-1, -1), 18),
    ]))
    e.append(bt); e.append(sp(16))

    feat = [
        ("10 Body Systems", "Complete coverage\nwith clinical notes"),
        ("Normal Values",   "All reference ranges\nyou must memorise"),
        ("Concept Boxes",   "Key mechanisms &\nclinical links"),
        ("50-MCQ Mock Test","Full section mock\nwith answers"),
    ]
    fc = []
    for t_, v_ in feat:
        fc.append(p(f"<b><font size='10'>{t_}</font></b><br/>"
                    f"<font size='8.5' color='#455A64'>{v_}</font>"))
    ft = Table([fc], colWidths=[TW / 4] * 4)
    ft.setStyle(TableStyle([
        ("BACKGROUND",   (0, 0), (-1, -1), ICE),
        ("BOX",          (0, 0), (-1, -1), 1, SKY),
        ("LINEAFTER",    (0, 0), (-2, -1), 0.5, SKY),
        ("ALIGN",        (0, 0), (-1, -1), "CENTER"),
        ("VALIGN",       (0, 0), (-1, -1), "MIDDLE"),
        ("TOPPADDING",   (0, 0), (-1, -1), 10),
        ("BOTTOMPADDING",(0, 0), (-1, -1), 10),
    ]))
    e.append(ft); e.append(sp(14))

    chapters = [
        "Ch 1 – Introduction: Levels of Organisation & Cell Biology",
        "Ch 2 – Cardiovascular System",
        "Ch 3 – Respiratory System",
        "Ch 4 – Renal / Urinary System",
        "Ch 5 – Digestive System & Liver",
        "Ch 6 – Endocrine System",
        "Ch 7 – Nervous System & Special Senses",
        "Ch 8 – Musculoskeletal System & Blood",
        "Ch 9 – Reproductive & Immune Systems",
        "Ch 10 – Quick-Reference Tables + 50-Question Mock Test",
    ]
    for ch in chapters:
        e.append(p(f"&#x25B6;  {ch}", toc_s))

    e.append(sp(24))
    e.append(p("Prepared for: ASI Paramedical Exam 2026 — CISF & BSF",
               S("F", fontName="Helvetica-Oblique", fontSize=8.5,
                 textColor=GREY_M, alignment=TA_CENTER)))
    e.append(pg())
    return e


# ══════════════════════════════════════════════════════════════
# CHAPTER 1 – CELL & ORGANISATION
# c1, c2, c3 = column widths; must sum to TW
# ══════════════════════════════════════════════════════════════
def ch1():
    e = []
    e.append(ChapterHeader("1", "Levels of Organisation & Cell Biology", NAVY)); e.append(sp(10))

    e.append(p("1.1  Levels of Structural Organisation", sec_h))
    # 3 cols: 3.5 + 6 + TW-9.5
    c1, c2, c3 = 3.5*cm, 6*cm, TW - 9.5*cm
    e.append(tbl(
        [["Level", "Definition", "Example"],
         ["Chemical / Atomic", "Atoms and molecules", "H₂O, DNA, ATP, glucose"],
         ["Cellular", "Basic unit of life", "Neurons, RBCs, hepatocytes"],
         ["Tissue", "Group of similar cells", "Epithelial, connective, muscle, nervous"],
         ["Organ", "Two or more tissue types", "Heart, liver, kidney, lung"],
         ["Organ System", "Related organs working together", "Cardiovascular, digestive, nervous"],
         ["Organism", "All organ systems combined", "Human body"]],
        cw=[c1, c2, c3]))
    e.append(sp(10))

    e.append(p("1.2  The Cell – Key Organelles & Functions", sec_h))
    c1, c2, c3 = 4*cm, 6*cm, TW - 10*cm
    e.append(tbl(
        [["Organelle", "Function", "Clinical Note"],
         ["Nucleus", "Contains DNA; controls all cell activity", "Absent in mature RBCs (anucleate)"],
         ["Mitochondria", "ATP production via cellular respiration", "'Powerhouse of cell'; maternally inherited DNA"],
         ["Ribosomes", "Protein synthesis (translation)", "RER-bound = secretory proteins"],
         ["Rough ER (RER)", "Protein synthesis + folding + transport", "Abundant in secretory cells (plasma cells, hepatocytes)"],
         ["Smooth ER (SER)", "Lipid & steroid synthesis; detoxification", "Abundant in liver, adrenal cortex, gonads"],
         ["Golgi Apparatus", "Packages and exports proteins/lipids", "'Post office of the cell'"],
         ["Lysosomes", "Intracellular digestion; contain hydrolases", "Failure → lysosomal storage diseases (Gaucher, Tay-Sachs)"],
         ["Cell Membrane", "Selective permeability; receptor site", "Phospholipid bilayer + cholesterol + proteins"],
         ["Centrioles", "Form mitotic spindle during cell division", "Absent in mature neurons and cardiac muscle"]],
        cw=[c1, c2, c3]))
    e.append(sp(10))

    e.append(p("1.3  Four Types of Body Tissues", sec_h))
    c1, c2, c3 = 3*cm, 5.5*cm, TW - 8.5*cm
    e.append(tbl(
        [["Tissue Type", "Sub-types", "Location / Function"],
         ["Epithelial", "Simple / Stratified; Squamous / Cuboidal / Columnar / Ciliated / Pseudostratified",
          "Covers surfaces, lines cavities; absorption, secretion, protection. Avascular – nutrients by diffusion."],
         ["Connective", "Loose, Dense (regular/irregular), Adipose, Cartilage (hyaline/elastic/fibrocartilage), Bone, Blood",
          "Supports, binds, fills spaces; immune defence, transport (blood)"],
         ["Muscle", "Skeletal (voluntary, striated, multi-nucleated), Cardiac (involuntary, striated, intercalated discs), Smooth (involuntary, non-striated)",
          "Movement; pump blood; peristalsis; maintains tone"],
         ["Nervous", "Neurons (sensory, motor, interneuron) + Neuroglia (Astrocytes, Microglia, Oligodendrocytes, Schwann cells, Ependymal cells)",
          "Electrical impulse generation and transmission; coordination; homeostasis"]],
        cw=[c1, c2, c3]))
    e.append(sp(8))
    e.append(box([p("<b>Key Fact:</b> Epithelial tissue is AVASCULAR (no blood vessels). It receives nutrients by diffusion from underlying connective tissue. This is why avascular epithelium heals slowly.", note)],
                 bg=AMB_LT, border=AMBER))
    e.append(pg()); return e


# ══════════════════════════════════════════════════════════════
# CHAPTER 2 – CARDIOVASCULAR
# ══════════════════════════════════════════════════════════════
def ch2():
    e = []
    e.append(ChapterHeader("2", "Cardiovascular System", HexColor("#B71C1C"))); e.append(sp(10))

    e.append(p("2.1  Heart Chambers", sec_h))
    c1, c2, c3, c4 = 3*cm, 3*cm, 5.5*cm, TW - 11.5*cm
    e.append(tbl(
        [["Chamber", "Blood Type", "Receives From", "Pumps To"],
         ["Right Atrium",   "Deoxygenated", "Superior / Inferior vena cava + Coronary sinus", "Right ventricle via Tricuspid valve"],
         ["Right Ventricle","Deoxygenated", "Right atrium",        "Pulmonary artery → Lungs (Pulmonary valve)"],
         ["Left Atrium",    "Oxygenated",   "4 Pulmonary veins",   "Left ventricle via Mitral (Bicuspid) valve"],
         ["Left Ventricle", "Oxygenated",   "Left atrium",         "Aorta → Systemic circulation (Aortic valve)"]],
        cw=[c1, c2, c3, c4], hbg=RED))
    e.append(sp(6))
    e.append(box([p("<b>Valve mnemonic:</b>  'Try Pulling My Aorta'  →  Tricuspid · Pulmonary · Mitral/Bicuspid · Aortic", note)], bg=RED_LT, border=RED))
    e.append(sp(10))

    e.append(p("2.2  Cardiac Conduction System", sec_h))
    c1, c2, c3 = 4.5*cm, 4.5*cm, TW - 9*cm
    e.append(tbl(
        [["Structure", "Location", "Role"],
         ["SA Node (Pacemaker)", "Right atrial wall",               "Fires 60–100/min; initiates sinus rhythm"],
         ["AV Node",            "Base of right atrium",            "Delays impulse 0.1 s; lets atria contract first"],
         ["Bundle of His",      "Interventricular septum (top)",   "Conducts impulse from AV node to ventricles"],
         ["L & R Bundle Branches","Interventricular septum",       "Distribute impulse to respective ventricle walls"],
         ["Purkinje Fibres",    "Ventricular myocardium",          "Rapid terminal spread → simultaneous ventricular contraction"]],
        cw=[c1, c2, c3], hbg=RED))
    e.append(sp(8))
    e.append(box([
        p("<b>ECG Wave Meanings</b>", sub_h),
        p("P wave = Atrial depolarisation (SA node fires)"),
        p("QRS complex = Ventricular depolarisation  |  Normal duration < 0.12 s"),
        p("T wave = Ventricular repolarisation"),
        p("PR interval = AV node conduction delay  (Normal 0.12–0.20 s)"),
        p("Broad QRS = Bundle branch block  |  Absent P waves = Atrial fibrillation"),
    ], bg=RED_LT, border=RED))
    e.append(sp(10))

    e.append(p("2.3  Blood Pressure & Cardiovascular Values", sec_h))
    c1, c2, c3 = 5*cm, 4.5*cm, TW - 9.5*cm
    e.append(tbl(
        [["Parameter", "Normal Value", "Clinical Note"],
         ["Blood Pressure",        "120/80 mmHg",   "HTN > 140/90;  Hypotension < 90/60"],
         ["Pulse Rate",            "60–100 /min",   "Bradycardia < 60;  Tachycardia > 100"],
         ["Stroke Volume",         "~70 mL/beat",   "Reduced in heart failure"],
         ["Cardiac Output",        "~5 L/min",      "CO = SV × HR  (70 × 72 ≈ 5 L/min)"],
         ["Pulse Pressure",        "~40 mmHg",      "Systolic − Diastolic;  widened in aortic regurgitation"],
         ["Mean Arterial Pressure","~93 mmHg",      "Diastolic + ⅓ Pulse Pressure; key organ perfusion pressure"]],
        cw=[c1, c2, c3], hbg=RED))
    e.append(sp(10))

    e.append(p("2.4  Blood Vessels Comparison", sec_h))
    c1, c2, c3, c4 = 2.8*cm, 3.2*cm, 4.5*cm, TW - 10.5*cm
    e.append(tbl(
        [["Vessel", "Wall", "Carries", "Key Feature"],
         ["Arteries",    "Thick, muscular, elastic",         "Oxygenated (except pulm. artery)", "High pressure; pulsatile"],
         ["Arterioles",  "Smooth muscle dominant",           "Oxygenated → capillaries",         "Main resistance vessels; regulate BP"],
         ["Capillaries", "Single endothelial cell layer",    "Exchange O₂, CO₂, nutrients, waste","Site of exchange; 1-cell thick"],
         ["Venules",     "Thin",                             "Deoxygenated from capillaries",    "Low pressure"],
         ["Veins",       "Thin wall; valves prevent backflow","Deoxygenated (except pulm. vein)", "Hold 60–70% of blood volume"],
         ["Pulm. artery","Thick",                            "Deoxygenated RV → Lungs",          "Only artery carrying deoxygenated blood"],
         ["Pulm. vein",  "Thin",                             "Oxygenated Lungs → Left atrium",   "Only vein carrying oxygenated blood"]],
        cw=[c1, c2, c3, c4], hbg=RED))
    e.append(pg()); return e


# ══════════════════════════════════════════════════════════════
# CHAPTER 3 – RESPIRATORY
# ══════════════════════════════════════════════════════════════
def ch3():
    e = []
    e.append(ChapterHeader("3", "Respiratory System", HexColor("#006064"))); e.append(sp(10))

    e.append(p("3.1  Respiratory Tract Anatomy", sec_h))
    c1, c2, c3 = 4*cm, 5*cm, TW - 9*cm
    e.append(tbl(
        [["Structure", "Description", "Function"],
         ["Nasal cavity",       "Lined with mucosa + cilia; rich blood supply",    "Filters, warms, humidifies inhaled air"],
         ["Pharynx",            "Nasopharynx + Oropharynx + Laryngopharynx",       "Common passage for air and food"],
         ["Larynx",             "Voice box; epiglottis (covers larynx during swallowing); thyroid + cricoid cartilage", "Sound production; prevents aspiration"],
         ["Trachea",            "~11 cm; 16–20 C-shaped hyaline cartilage rings; ciliated pseudostratified epithelium", "Main airway; mucociliary escalator clears debris"],
         ["Primary Bronchi",    "Right = wider, shorter, more vertical → more likely to inhale foreign bodies", "Air to each lung"],
         ["Secondary Bronchi",  "3 right (for 3 lobes) / 2 left (for 2 lobes)",   "Air to each lobe"],
         ["Bronchioles",        "No cartilage; smooth muscle (spasm = asthma)",    "Regulate airflow; bronchoconstriction / dilation"],
         ["Alveoli",            "300 million; Type I (gas exchange) + Type II (surfactant)", "O₂/CO₂ exchange across 1-cell wall"]],
        cw=[c1, c2, c3], hbg=HexColor("#006064")))
    e.append(sp(8))
    e.append(box([
        p("<b>Type I Pneumocytes</b> – Flat, squamous; form 95% of alveolar surface; site of gas exchange.", body),
        p("<b>Type II Pneumocytes</b> – Cuboidal; secrete surfactant (DPPC – dipalmitoyl phosphatidylcholine). Reduce surface tension, prevent alveolar collapse.", body),
        p("<b>Clinical:</b> Premature infants lack surfactant → Respiratory Distress Syndrome (RDS / Hyaline Membrane Disease). Treated with exogenous surfactant + corticosteroids.", warn),
    ], bg=TEAL_LT, border=TEAL))
    e.append(sp(10))

    e.append(p("3.2  Lung Volumes & Capacities", sec_h))
    c1, c2, c3 = 5.5*cm, 3*cm, TW - 8.5*cm
    e.append(tbl(
        [["Parameter", "Value", "Definition"],
         ["Tidal Volume (TV)",                "500 mL",   "Air moved in/out in one normal breath at rest"],
         ["Inspiratory Reserve Volume (IRV)", "3000 mL",  "Extra air inhaled beyond normal inspiration"],
         ["Expiratory Reserve Volume (ERV)",  "1100 mL",  "Extra air exhaled beyond normal expiration"],
         ["Residual Volume (RV)",             "1200 mL",  "Air remaining after maximal expiration (cannot be exhaled)"],
         ["Vital Capacity (VC)",              "4600 mL",  "TV + IRV + ERV; max air exhaled after max inspiration"],
         ["Total Lung Capacity (TLC)",        "5800 mL",  "VC + RV; total air at maximum inspiration"],
         ["Functional Residual Capacity (FRC)","2300 mL", "ERV + RV; air remaining after normal expiration"],
         ["FEV₁/FVC ratio",                  "≥ 70%",    "< 70% = obstructive (asthma, COPD); normal or ↑ in restrictive"]],
        cw=[c1, c2, c3], hbg=HexColor("#006064")))
    e.append(sp(10))

    e.append(p("3.3  Blood Gas Values & Acid-Base Disorders", sec_h))
    c1, c2, c3, c4 = 5*cm, 3*cm, 3*cm, TW - 11*cm
    e.append(tbl(
        [["Disorder",             "pH",   "PaCO₂",  "HCO₃⁻",   "Cause"],
         ["Normal",               "7.35–7.45", "35–45 mmHg", "22–26 mEq/L", "—"],
         ["Respiratory Acidosis", "↓",    "↑",      "Normal/↑ (compensated)", "Hypoventilation, COPD, narcotic overdose"],
         ["Respiratory Alkalosis","↑",    "↓",      "Normal/↓ (compensated)", "Hyperventilation, anxiety, altitude"],
         ["Metabolic Acidosis",   "↓",    "Normal/↓","↓",       "DKA, renal failure, severe diarrhoea, lactic acidosis"],
         ["Metabolic Alkalosis",  "↑",    "Normal/↑","↑",       "Vomiting (HCl loss), diuretics, antacid excess"]],
        cw=[c1, c2, c3, TW-c1-c2-c3], hbg=HexColor("#006064")))
    e.append(pg()); return e


# ══════════════════════════════════════════════════════════════
# CHAPTER 4 – RENAL
# ══════════════════════════════════════════════════════════════
def ch4():
    e = []
    e.append(ChapterHeader("4", "Renal / Urinary System", HexColor("#1A237E"))); e.append(sp(10))

    e.append(p("4.1  Nephron – Step-by-Step", sec_h))
    c1, c2, c3 = 4.5*cm, 3*cm, TW - 7.5*cm
    e.append(tbl(
        [["Nephron Part", "Location", "Function"],
         ["Glomerulus + Bowman's Capsule", "Renal cortex", "Filtration: blood filtered at 125 mL/min → ultrafiltrate (water, salts, glucose, urea, amino acids — NO proteins or RBCs)"],
         ["Proximal Convoluted Tubule (PCT)", "Renal cortex", "Reabsorbs 65–70% of filtered Na⁺, water, ALL glucose, amino acids, HCO₃⁻, uric acid (obligatory reabsorption)"],
         ["Descending Loop of Henle", "Renal medulla", "Permeable to water ONLY → water leaves; filtrate becomes concentrated"],
         ["Ascending Loop of Henle", "Renal medulla", "Impermeable to water; NaCl actively pumped out → creates medullary osmotic gradient (concentration mechanism)"],
         ["Distal Convoluted Tubule (DCT)", "Renal cortex", "Na⁺ reabsorption (under Aldosterone); Ca²⁺ reabsorption (under PTH); H⁺ and K⁺ secretion"],
         ["Collecting Duct", "Renal medulla → papilla", "Water reabsorption controlled by ADH/Vasopressin; determines final urine concentration; urea recycling"]],
        cw=[c1, c2, c3], hbg=HexColor("#1A237E")))
    e.append(sp(10))

    e.append(p("4.2  CKD Staging (Based on GFR)", sec_h))
    c1, c2, c3 = 3*cm, 5.5*cm, TW - 8.5*cm
    e.append(tbl(
        [["CKD Stage", "GFR (mL/min/1.73 m²)", "Clinical Status"],
         ["Stage 1", "≥ 90  (with kidney damage markers)", "Normal or high GFR + evidence of damage (proteinuria, haematuria)"],
         ["Stage 2", "60–89", "Mildly decreased; often asymptomatic"],
         ["Stage 3a", "45–59", "Mild-to-moderate decrease; monitor closely"],
         ["Stage 3b", "30–44", "Moderate-to-severe decrease; treat complications"],
         ["Stage 4", "15–29", "Severely decreased; prepare for renal replacement therapy"],
         ["Stage 5", "< 15",  "Kidney failure; dialysis or transplant needed"]],
        cw=[c1, c2, c3], hbg=HexColor("#1A237E")))
    e.append(sp(10))

    e.append(p("4.3  Normal Urine Characteristics", sec_h))
    c1, c2, c3 = 3.5*cm, 4*cm, TW - 7.5*cm
    e.append(tbl(
        [["Property", "Normal Value", "Abnormal Significance"],
         ["Volume/day",        "1000–2000 mL",          "Oliguria < 400 mL/day; Anuria < 100 mL/day; Polyuria > 3000 mL/day"],
         ["Colour",            "Pale to amber yellow",  "Dark = concentrated/jaundice; Red/pink = haematuria; Cloudy = pyuria/phosphaturia"],
         ["pH",                "4.5–8.0 (avg 6.0)",     "Alkaline in UTI (urease-splitting bacteria); Acidic in starvation/acidosis"],
         ["Specific Gravity",  "1.002–1.030",           "Low (< 1.005) = Diabetes insipidus / overhydration; High = dehydration"],
         ["Protein",           "< 150 mg/day (nil dipstick)", "Proteinuria = nephrotic syndrome, glomerulonephritis, preeclampsia"],
         ["Glucose",           "Nil (renal threshold 180 mg/dL)", "Glycosuria = DM, renal glycosuria (normal glucose but low threshold)"],
         ["Ketones",           "Nil",                   "Ketonuria = DKA, starvation, prolonged vomiting, low-carb diet"],
         ["RBCs",              "0–2 per HPF",            "Haematuria = stones, UTI, cancer, trauma, glomerulonephritis"],
         ["WBCs",              "0–5 per HPF",            "Pyuria = UTI, pyelonephritis, TB of kidney"],
         ["Casts",             "Occasional hyaline",    "RBC casts = glomerulonephritis; Granular casts = AKI; Fatty casts = nephrotic syndrome"]],
        cw=[c1, c2, c3], hbg=HexColor("#1A237E")))
    e.append(sp(8))
    e.append(box([
        p("<b>Hormones controlling renal function:</b>", sub_h),
        p("ADH (Vasopressin) — posterior pituitary → water reabsorption in collecting duct → concentrated urine"),
        p("Aldosterone — adrenal cortex → Na⁺ reabsorption + K⁺/H⁺ excretion in DCT → water follows Na⁺ → raises BP"),
        p("ANP (Atrial Natriuretic Peptide) — cardiac atria → promotes Na⁺/water excretion → lowers BP"),
        p("Erythropoietin (EPO) — peritubular cells → stimulates RBC production in bone marrow"),
        p("RAAS: Renin (kidney) → Angiotensin I → ACE (lungs) → Angiotensin II → vasoconstriction + aldosterone release"),
    ], bg=ICE, border=SKY))
    e.append(pg()); return e


# ══════════════════════════════════════════════════════════════
# CHAPTER 5 – DIGESTIVE
# ══════════════════════════════════════════════════════════════
def ch5():
    e = []
    e.append(ChapterHeader("5", "Digestive System & Liver", HexColor("#33691E"))); e.append(sp(10))

    e.append(p("5.1  GI Tract – Organs, Secretions & Functions", sec_h))
    c1, c2, c3 = 4*cm, 5*cm, TW - 9*cm
    e.append(tbl(
        [["Organ", "Key Secretions", "Function"],
         ["Mouth / Salivary glands",  "Salivary amylase (ptyalin), mucus, lingual lipase, IgA", "Starch digestion begins; food bolus formation; antimicrobial IgA"],
         ["Oesophagus",               "Mucus only",  "Peristalsis transports food to stomach; no digestion; lower oesophageal sphincter prevents reflux"],
         ["Stomach",                  "HCl (parietal cells), Pepsinogen (chief cells), Intrinsic Factor (parietal), Gastrin, Mucus (goblet)", "Protein digestion (pepsin at pH 1.5–3.5); kills bacteria; chyme formation; B12 absorption (IF)"],
         ["Duodenum",                 "Receives: bile (gallbladder) + pancreatic juice (bicarbonate, enzymes); Secretin + CCK secreted", "Most active digestion zone; neutralises acid chyme; fat + protein breakdown"],
         ["Jejunum",                  "Brush-border enzymes: maltase, lactase, sucrase, aminopeptidase", "PRIMARY site of nutrient ABSORPTION (sugars, amino acids, fatty acids, vitamins)"],
         ["Ileum",                    "Bile salt reabsorption (enterohepatic circulation)", "Absorption of Vit B12 (IF complex), fat-soluble vitamins (A D E K), bile salts"],
         ["Colon",                    "Mucus only",  "Water + electrolyte reabsorption; bacterial fermentation of fibre; faeces formation"],
         ["Rectum + Anal canal",      "Mucus",       "Storage and controlled defaecation"]],
        cw=[c1, c2, c3], hbg=HexColor("#33691E")))
    e.append(sp(10))

    e.append(p("5.2  Pancreatic Enzymes (All Secreted as Inactive Zymogens)", sec_h))
    c1, c2, c3, c4 = 4*cm, 3.5*cm, 5*cm, TW - 12.5*cm
    e.append(tbl(
        [["Enzyme", "Zymogen", "Substrate", "Activated By"],
         ["Trypsin",         "Trypsinogen",        "Proteins → peptides (cleaves Arg/Lys bonds)", "Enterokinase (brush border of duodenum)"],
         ["Chymotrypsin",    "Chymotrypsinogen",   "Proteins → peptides (cleaves Phe/Tyr/Trp bonds)", "Trypsin"],
         ["Elastase",        "Proelastase",        "Elastin and other structural proteins", "Trypsin"],
         ["Carboxypeptidase","Procarboxypeptidase","Peptides → amino acids (from C-terminal end)", "Trypsin"],
         ["Pancreatic Amylase","— (active as secreted)","Starch → maltose + dextrins", "—"],
         ["Pancreatic Lipase","— (active)","Triglycerides → fatty acids + 2-monoglycerol", "Requires bile salts to emulsify fat first"],
         ["Phospholipase A₂","Prophospholipase",  "Phospholipids → lysophospholipids + FA", "Trypsin"]],
        cw=[c1, c2, c3, c4], hbg=HexColor("#33691E")))
    e.append(sp(10))

    e.append(p("5.3  Liver Functions", sec_h))
    c1, c2 = 3.5*cm, TW - 3.5*cm
    e.append(tbl(
        [["Function", "Detail"],
         ["Bile Production",   "600–1000 mL/day; stored in gallbladder; bile salts emulsify dietary fats for lipase action; bilirubin excreted in bile"],
         ["Carbohydrate metabolism", "Glycogenesis (glucose → glycogen storage); Glycogenolysis (glycogen → glucose release); Gluconeogenesis (amino acids/lactate → glucose during fasting)"],
         ["Protein metabolism","Deamination of amino acids; Urea cycle (toxic NH₃ → urea); synthesises albumin, fibrinogen, prothrombin, clotting factors II VII IX X"],
         ["Fat metabolism",    "Beta-oxidation of fatty acids; Ketone body synthesis; Cholesterol synthesis (70%); Lipoprotein assembly (VLDL)"],
         ["Detoxification",    "Cytochrome P450 system metabolises drugs, alcohol, toxins; First-pass metabolism of oral drugs (reduces bioavailability)"],
         ["Storage",           "Glycogen; Fat-soluble vitamins (A, D, E, K); Vitamin B12 (3–5 year store); Iron as ferritin and haemosiderin; Copper"],
         ["Bilirubin metabolism","Haemoglobin → Haem → Biliverdin → Unconjugated bilirubin (bound albumin, water-insoluble) → Liver adds glucuronic acid → Conjugated bilirubin (water-soluble) → Bile → Gut → Urobilinogen → Stercobilin (faeces) / Urobilin (urine)"],
         ["Jaundice types",    "Pre-hepatic (haemolytic): ↑ unconjugated; Hepatic (hepatocellular): ↑ both; Post-hepatic (obstructive): ↑ conjugated, pale stools, dark urine"]],
        cw=[c1, c2], hbg=HexColor("#33691E")))
    e.append(pg()); return e


# ══════════════════════════════════════════════════════════════
# CHAPTER 6 – ENDOCRINE
# ══════════════════════════════════════════════════════════════
def ch6():
    e = []
    e.append(ChapterHeader("6", "Endocrine System", HexColor("#4A0072"))); e.append(sp(10))

    e.append(p("6.1  Major Endocrine Glands & Hormones", sec_h))
    c1, c2, c3, c4 = 3.5*cm, 4.5*cm, 4.5*cm, TW - 12.5*cm
    e.append(tbl(
        [["Gland", "Hormone(s)", "Main Function", "Deficiency / Excess"],
         ["Anterior Pituitary",   "GH, TSH, ACTH, FSH, LH, Prolactin",          "Controls other endocrine glands; growth; reproduction",         "GH↓ = dwarfism; GH↑ = acromegaly (adult); prolactin↑ = galactorrhoea"],
         ["Posterior Pituitary",  "ADH (Vasopressin), Oxytocin",                 "ADH: water conservation; Oxytocin: uterine contraction + milk ejection", "ADH↓ = Diabetes Insipidus (dilute polyuria)"],
         ["Thyroid",              "T3, T4 (Thyroxine), Calcitonin",              "Basal metabolic rate; growth; CNS development; Ca²⁺ lowering (calcitonin)", "Hypo: Myxoedema (adult), Cretinism (child); Hyper: Graves' disease"],
         ["Parathyroid (×4)",     "Parathyroid Hormone (PTH)",                   "Raises serum Ca²⁺: bone resorption ↑, renal Ca²⁺ reabsorption ↑, Vit D activation ↑", "↓ = Hypocalcaemia, tetany, Chvostek sign; ↑ = Hypercalcaemia, stones"],
         ["Adrenal Cortex",       "Cortisol (Zona Fasciculata), Aldosterone (Zona Glomerulosa), Androgens (Zona Reticularis)", "Stress response; anti-inflammatory; Na⁺/K⁺ balance; sex characteristics", "Addison's (↓ cortisol + aldosterone); Cushing's (↑ cortisol); Conn's (↑ aldosterone)"],
         ["Adrenal Medulla",      "Adrenaline (Epinephrine), Noradrenaline",     "Fight-or-flight: ↑HR, ↑BP, ↑blood glucose, bronchodilation, ↑sweating", "Phaeochromocytoma = paroxysmal hypertension + headache + palpitations"],
         ["Pancreas β-cells",     "Insulin",                                     "Lowers blood glucose; promotes glycogenesis, lipogenesis, protein synthesis; K⁺ uptake into cells", "Type 1 DM (absent); Type 2 DM (resistant)"],
         ["Pancreas α-cells",     "Glucagon",                                    "Raises blood glucose (glycogenolysis + gluconeogenesis)",        "Glucagonoma = hyperglycaemia + necrolytic migratory erythema"],
         ["Pineal Gland",         "Melatonin",                                   "Regulates circadian rhythm; suppressed by light",               "Disrupted in shift work, jet lag"],
         ["Thymus",               "Thymosin",                                    "T-lymphocyte maturation (childhood); involutes in adulthood",   "Associated with myasthenia gravis (thymoma)"]],
        cw=[c1, c2, c3, c4], hbg=HexColor("#4A0072")))
    e.append(sp(8))
    e.append(box([
        p("<b>Blood Sugar Regulation:</b>", sub_h),
        p("After eating → Blood glucose ↑ → Beta cells → Insulin → Glucose into cells; glycogenesis; lipogenesis → Glucose ↓"),
        p("Fasting → Blood glucose ↓ → Alpha cells → Glucagon → Glycogenolysis + gluconeogenesis in liver → Glucose ↑"),
        p("Counter-regulatory hormones (all RAISE glucose): Cortisol, GH, Adrenaline, Glucagon"),
        p("Diabetes Mellitus diagnosis: FBG ≥ 126 mg/dL OR HbA1c ≥ 6.5% OR 2-hr OGTT ≥ 200 mg/dL", warn),
    ], bg=PUR_LT, border=PURPLE))
    e.append(pg()); return e


# ══════════════════════════════════════════════════════════════
# CHAPTER 7 – NERVOUS SYSTEM
# ══════════════════════════════════════════════════════════════
def ch7():
    e = []
    e.append(ChapterHeader("7", "Nervous System & Special Senses", HexColor("#01579B"))); e.append(sp(10))

    e.append(p("7.1  Divisions of the Nervous System", sec_h))
    c1, c2, c3 = 4.5*cm, 3.5*cm, TW - 8*cm
    e.append(tbl(
        [["Division", "Sub-division", "Components / Role"],
         ["CNS",  "Brain",             "Cerebrum, Cerebellum, Brainstem, Diencephalon (thalamus, hypothalamus)"],
         ["CNS",  "Spinal cord",       "31 pairs of spinal nerves; ascending sensory tracts + descending motor tracts; reflex arcs"],
         ["PNS",  "Somatic NS",        "Voluntary control of skeletal muscle; conscious sensory input"],
         ["PNS",  "Sympathetic ANS",   "Fight-or-flight: ↑HR, ↑BP, dilates pupils (mydriasis), bronchodilation, ↓digestion, ↑sweating"],
         ["PNS",  "Parasympathetic ANS","Rest-and-digest: ↓HR, stimulates digestion, constricts pupils (miosis), bronchoconstriction, ↑salivation"]],
        cw=[c1, c2, c3], hbg=HexColor("#01579B")))
    e.append(sp(10))

    e.append(p("7.2  Brain Regions & Functions", sec_h))
    c1, c2, c3 = 3.5*cm, 4.5*cm, TW - 8*cm
    e.append(tbl(
        [["Region", "Key Sub-areas", "Functions"],
         ["Cerebrum (Largest part)", "Frontal, Parietal, Temporal, Occipital lobes; Motor cortex, Sensory cortex, Broca's & Wernicke's areas", "Frontal = voluntary movement + personality + judgment; Parietal = sensation + spatial; Temporal = hearing + memory + language; Occipital = vision"],
         ["Cerebellum", "Vermis (midline), Lateral hemispheres", "Coordination; balance; fine motor control; posture. Damage → Ataxia, intention tremor, dysmetria"],
         ["Brainstem", "Midbrain, Pons, Medulla oblongata", "Medulla = vital centres (HR, breathing, BP, vomiting, swallowing); Pons = sleep, REM; Midbrain = CN III, IV (eye movement), relay"],
         ["Thalamus", "Multiple nuclei", "Relay station for ALL sensory signals to cortex (except smell); gating sensory input"],
         ["Hypothalamus", "Multiple nuclei", "Regulates: body temperature, hunger, thirst, sleep-wake cycle, circadian rhythm, pituitary gland; links nervous + endocrine systems"],
         ["Limbic System", "Hippocampus, Amygdala, Cingulate gyrus", "Hippocampus = memory consolidation (new declarative memories); Amygdala = fear, emotion, aggression; Limbic = emotional behaviour"]],
        cw=[c1, c2, c3], hbg=HexColor("#01579B")))
    e.append(sp(10))

    e.append(p("7.3  12 Cranial Nerves", sec_h))
    c1, c2, c3, c4 = 1.5*cm, 4*cm, 2.5*cm, TW - 8*cm
    e.append(tbl(
        [["No.", "Name", "Type", "Function"],
         ["I",   "Olfactory",         "Sensory",     "Smell"],
         ["II",  "Optic",             "Sensory",     "Vision"],
         ["III", "Oculomotor",        "Motor (+ PS)","Eye movement (4 of 6 muscles); pupil constriction; upper eyelid; lens accommodation"],
         ["IV",  "Trochlear",         "Motor",       "Superior oblique muscle → eye movement (intorsion + downward gaze)"],
         ["V",   "Trigeminal",        "Both",        "Sensation from face (V1 ophthalmic, V2 maxillary, V3 mandibular); mastication (chewing)"],
         ["VI",  "Abducens",          "Motor",       "Lateral rectus muscle → lateral eye movement; CN VI palsy → medial deviation (esotropia)"],
         ["VII", "Facial",            "Both",        "Facial expression (all muscles); taste anterior 2/3 tongue; lacrimation; salivation"],
         ["VIII","Vestibulocochlear", "Sensory",     "Hearing (Cochlear division) + Balance/vestibular sense"],
         ["IX",  "Glossopharyngeal",  "Both",        "Taste posterior 1/3 tongue; swallowing; parotid secretion; carotid sinus reflex"],
         ["X",   "Vagus",             "Both",        "Parasympathetic to heart, lungs, GI; motor for larynx, pharynx; visceral sensation"],
         ["XI",  "Accessory",         "Motor",       "Sternocleidomastoid + Trapezius muscles (head turning + shoulder shrugging)"],
         ["XII", "Hypoglossal",       "Motor",       "All intrinsic + most extrinsic tongue muscles; tongue movement + speech"]],
        cw=[c1, c2, c3, c4], hbg=HexColor("#01579B")))
    e.append(sp(8))
    e.append(box([
        p("<b>Mnemonic for Cranial Nerve Names:</b> 'Oh, Oh, Oh, To Touch And Feel Very Good Velvet, Ah Heaven!'  (I–XII)", note),
        p("<b>Blood-Brain Barrier (BBB):</b> Tight junctions between brain capillary endothelial cells + astrocyte foot processes. Allows O₂, CO₂, glucose, lipid-soluble substances. Blocks bacteria, most water-soluble drugs. Disrupted in meningitis, trauma, tumours.", note),
    ], bg=AMB_LT, border=AMBER))
    e.append(pg()); return e


# ══════════════════════════════════════════════════════════════
# CHAPTER 8 – MUSCULOSKELETAL + BLOOD
# ══════════════════════════════════════════════════════════════
def ch8():
    e = []
    e.append(ChapterHeader("8", "Musculoskeletal System & Blood", HexColor("#BF360C"))); e.append(sp(10))

    e.append(p("8.1  Skeletal System Key Facts", sec_h))
    c1, c2 = 5*cm, TW - 5*cm
    e.append(tbl(
        [["Fact", "Detail"],
         ["Total bones (adults)",      "206 bones (infants have ~270–300; fuse during growth)"],
         ["Longest bone",              "Femur (thigh bone)"],
         ["Smallest bone",             "Stapes (in middle ear; ossicle)"],
         ["Largest joint",             "Knee joint (tibiofemoral)"],
         ["Hardest bone area",         "Petrous part of temporal bone"],
         ["Haematopoiesis (adult)",    "Red bone marrow — sternum, iliac crest, vertebrae, ribs, proximal femur/humerus"],
         ["Bone mineral",              "Hydroxyapatite crystals: Ca₁₀(PO₄)₆(OH)₂ (60–70% dry weight)"],
         ["Osteoblasts",               "Bone-forming cells (lay down osteoid matrix); stimulated by calcitonin + mechanical loading"],
         ["Osteoclasts",               "Bone-resorbing cells; activated by PTH and RANKL; inhibited by calcitonin + bisphosphonates"],
         ["Bone regulation",           "Calcium homeostasis: PTH ↑ Ca²⁺ (resorbs bone); Calcitonin ↓ Ca²⁺ (inhibits osteoclasts); Vitamin D ↑ GI Ca²⁺ absorption"],
         ["Fracture healing stages",   "1. Haematoma (0–1 week) → 2. Soft fibrocartilaginous callus (1–3 weeks) → 3. Hard bony callus (3–12 weeks) → 4. Remodelling (months–years)"]],
        cw=[c1, c2], hbg=HexColor("#BF360C")))
    e.append(sp(10))

    e.append(p("8.2  Muscle Types Compared", sec_h))
    c1, c2, c3, c4 = 3.5*cm, 4.5*cm, 4*cm, TW - 12*cm
    e.append(tbl(
        [["Feature",          "Skeletal Muscle",               "Cardiac Muscle",                    "Smooth Muscle"],
         ["Control",          "Voluntary (somatic NS)",        "Involuntary (ANS + intrinsic)",     "Involuntary (ANS)"],
         ["Striation",        "Yes (striated)",                "Yes (striated)",                    "No (non-striated)"],
         ["Nucleus",          "Multiple, peripheral",          "1–2, central",                      "Single, central"],
         ["Speed of contraction","Fast (white) or slow (red)", "Moderate",                          "Slow; sustained tone"],
         ["Intercalated discs","Absent",                       "Present (electrical coupling)",     "Absent"],
         ["Gap junctions",    "Absent",                        "Present (functional syncytium)",    "Present (visceral smooth muscle)"],
         ["Regeneration",     "Limited (satellite cells)",     "Minimal; replaced by fibrosis",     "Good (stem cells/pericytes)"],
         ["Location",         "Attached to bones",             "Heart wall (myocardium) only",      "Visceral organs, blood vessels, airways, skin"]],
        cw=[c1, c2, c3, c4], hbg=HexColor("#BF360C")))
    e.append(sp(10))

    e.append(p("8.3  Blood – Components & CBC Reference Values", sec_h))
    c1, c2, c3, c4 = 3.5*cm, 4.5*cm, 3*cm, TW - 11*cm
    e.append(tbl(
        [["Component",        "Male",              "Female",            "Key Facts"],
         ["RBC Count",        "4.5–5.5 M/µL",      "3.8–5.0 M/µL",     "No nucleus; lifespan ~120 days; destroyed in spleen; EPO stimulates production"],
         ["Hemoglobin",       "13–17 g/dL",        "12–15 g/dL",       "4 globin chains + 4 haem groups; HbA (α2β2) = adult Hb; carries O₂ + CO₂"],
         ["PCV/Hematocrit",   "40–54%",            "36–46%",           "% of blood volume occupied by RBCs"],
         ["MCV",              "80–100 fL",         "80–100 fL",        "< 80 = microcytic; > 100 = macrocytic"],
         ["MCH",              "27–33 pg",          "27–33 pg",         "Amount of Hb per RBC"],
         ["MCHC",             "32–36 g/dL",        "32–36 g/dL",       "Hb concentration per RBC volume; < 32 = hypochromic"],
         ["WBC Count",        "4,000–11,000/µL",   "4,000–11,000/µL",  "Differential: Neutrophils 60–70%, Lymphocytes 20–30%, Monocytes 2–8%, Eosinophils 1–4%, Basophils 0–1%"],
         ["Platelet Count",   "1.5–4 lakh/µL",     "1.5–4 lakh/µL",   "Formed from megakaryocytes; lifespan ~10 days; primary haemostatic plug"],
         ["ESR (Westergren)", "0–15 mm/hr",        "0–20 mm/hr",       "Raised in inflammation, infection, pregnancy, malignancy"],
         ["Reticulocyte count","0.5–1.5%",          "0.5–1.5%",        "Immature RBCs; ↑ = active erythropoiesis (haemolysis, blood loss, treatment response)"]],
        cw=[c1, c2, c3, c4], hbg=HexColor("#BF360C")))
    e.append(pg()); return e


# ══════════════════════════════════════════════════════════════
# CHAPTER 9 – REPRODUCTIVE + IMMUNE
# ══════════════════════════════════════════════════════════════
def ch9():
    e = []
    e.append(ChapterHeader("9", "Reproductive & Immune Systems", HexColor("#880E4F"))); e.append(sp(10))

    e.append(p("9.1  Male Reproductive Organs", sec_h))
    c1, c2 = 4.5*cm, TW - 4.5*cm
    e.append(tbl(
        [["Structure", "Function"],
         ["Testes",                 "Spermatogenesis (in seminiferous tubules; starts at puberty); Testosterone production (Leydig cells); FSH maintains spermatogenesis; LH stimulates testosterone"],
         ["Sertoli Cells",          "Nourish developing sperm ('nurse cells'); form blood-testis barrier; secrete inhibin (inhibits FSH); respond to FSH"],
         ["Epididymis",             "Sperm maturation (~3 weeks) and storage; sperm gain motility here"],
         ["Vas Deferens",           "Muscular tube transporting sperm from epididymis → ejaculatory duct; cut in vasectomy"],
         ["Seminal Vesicles",       "Contribute 60% of semen volume; fructose-rich (energy for sperm); prostaglandins; coagulation proteins"],
         ["Prostate Gland",         "30% of semen; alkaline secretion (protects sperm from acidic vagina); PSA (prostate-specific antigen); enlarged in BPH; cancer common in elderly males"],
         ["Bulbourethral / Cowper's Glands","Pre-ejaculatory mucus; lubricates urethra; neutralises acidity; may contain sperm (risk of pregnancy with pre-ejaculate)"]],
        cw=[c1, c2], hbg=HexColor("#880E4F")))
    e.append(sp(10))

    e.append(p("9.2  Menstrual Cycle (28-Day)", sec_h))
    c1, c2, c3, c4 = 4*cm, 2.5*cm, 4.5*cm, TW - 11*cm
    e.append(tbl(
        [["Phase", "Days", "Dominant Hormone", "Key Events"],
         ["Menstrual phase",        "1–5",  "All low",            "Shedding of endometrium (menses); prostaglandins cause uterine contractions"],
         ["Follicular / Proliferative","6–13", "Oestrogen ↑ (from follicle)", "FSH stimulates follicle growth; dominant follicle selected; oestrogen thickens endometrium + cervical mucus thinning"],
         ["Ovulation",              "Day 14","LH surge (sharp peak)", "LH surge → rupture of dominant follicle → secondary oocyte released; progesterone begins to rise"],
         ["Luteal / Secretory",     "15–28","Progesterone (from corpus luteum)", "Corpus luteum secretes progesterone; endometrium becomes secretory (glandular); prepares for implantation; if no pregnancy → corpus luteum degenerates → progesterone ↓ → menses begins"]],
        cw=[c1, c2, c3, c4], hbg=HexColor("#880E4F")))
    e.append(sp(8))
    e.append(box([
        p("hCG (human Chorionic Gonadotropin) = first hormone of pregnancy; secreted by trophoblast; maintains corpus luteum; basis of ALL pregnancy tests (urine + serum)"),
        p("Oestrogen = produced by ovarian follicle (pre-ovulation) and corpus luteum + placenta (pregnancy)"),
        p("Progesterone = 'hormone of pregnancy'; maintains endometrium; produced by corpus luteum then placenta after 8 weeks"),
    ], bg=PUR_LT, border=PURPLE))
    e.append(sp(10))

    e.append(p("9.3  Immune System – Key Comparison", sec_h))
    c1, c2, c3 = 3.5*cm, 5.5*cm, TW - 9*cm
    e.append(tbl(
        [["Feature", "Innate Immunity", "Adaptive Immunity"],
         ["Speed",       "Immediate (minutes–hours)", "Slow — 4–7 days (primary); faster on re-exposure (memory)"],
         ["Specificity", "Non-specific; recognises PAMPs via PRRs (Toll-like receptors)", "Highly specific; recognises specific antigens via TCR and BCR"],
         ["Memory",      "No immunological memory", "YES — memory T and B cells formed; basis of vaccination"],
         ["Components",  "Skin, mucus, cilia, stomach acid; Neutrophils, Macrophages, NK cells; Complement system; Interferons", "T lymphocytes (cellular: Th, Tc, Treg, Th17); B lymphocytes → Plasma cells → Antibodies"],
         ["Cells",       "Neutrophils, Macrophages, Dendritic cells, NK cells, Mast cells, Eosinophils, Basophils", "CD4+ T helper cells, CD8+ Cytotoxic T cells, B cells, Plasma cells, Memory cells"]],
        cw=[c1, c2, c3], hbg=HexColor("#880E4F")))
    e.append(sp(10))

    e.append(p("9.4  Immunoglobulin (Antibody) Classes", sec_h))
    c1, c2, c3 = 2.5*cm, 3.5*cm, TW - 6*cm
    e.append(tbl(
        [["Class", "% Serum Ig", "Key Function"],
         ["IgG", "75–80% (most abundant)", "Main serum antibody; only Ig to CROSS PLACENTA (passive immunity to foetus); secondary immune response; opsonisation; complement activation"],
         ["IgA", "10–15%", "SECRETORY antibody – breast milk, saliva, tears, mucus membranes; first line defence at mucosal surfaces (GI, respiratory tract)"],
         ["IgM", "5–10%", "FIRST antibody produced in primary response; PENTAMERIC (5 units joined by J chain); best complement activator; ABO blood group antibodies are IgM"],
         ["IgE", "< 0.001%", "Binds mast cells + basophils via Fc receptor; triggers Type I hypersensitivity (allergy, anaphylaxis, asthma); highly elevated in parasitic infections"],
         ["IgD", "< 1%", "Expressed on surface of naive B cells as antigen receptor; role in B cell activation and differentiation"]],
        cw=[c1, c2, c3], hbg=HexColor("#880E4F")))
    e.append(pg()); return e


# ══════════════════════════════════════════════════════════════
# CHAPTER 10 – REFERENCE TABLE + MOCK TEST
# ══════════════════════════════════════════════════════════════
def ch10():
    e = []
    e.append(ChapterHeader("10", "Quick-Reference Master Table & 50-Question Mock Test", NAVY)); e.append(sp(10))

    e.append(SectionBand("MASTER REFERENCE VALUE TABLE", ROYAL)); e.append(sp(6))
    c1, c2, c3, c4 = 5*cm, 4*cm, 3.5*cm, TW - 12.5*cm
    e.append(tbl(
        [["Parameter",              "Normal Value",     "High =",               "Low ="],
         ["Hb (Male)",              "13–17 g/dL",       "Polycythaemia",        "Anaemia"],
         ["Hb (Female)",            "12–15 g/dL",       "Polycythaemia",        "Anaemia"],
         ["RBC (Male)",             "4.5–5.5 M/µL",     "Polycythaemia vera",   "Anaemia"],
         ["WBC",                    "4,000–11,000/µL",  "Leukocytosis (infection/leukaemia)", "Leukopenia (viral, chemo)"],
         ["Platelets",              "1.5–4 lakh/µL",    "Thrombocytosis",       "Thrombocytopenia (bleeding risk)"],
         ["PCV/Hct (Male)",         "40–54%",           "Dehydration",          "Anaemia"],
         ["MCV",                    "80–100 fL",        "Macrocytosis (B12/folate↓)", "Microcytosis (Fe↓, thalassaemia)"],
         ["ESR (Male)",             "0–15 mm/hr",       "Inflammation/infection","—"],
         ["Blood pH",               "7.35–7.45",        "Alkalosis (> 7.45)",   "Acidosis (< 7.35)"],
         ["PaO₂",                   "80–100 mmHg",      "Hyperoxia",            "Hypoxia"],
         ["PaCO₂",                  "35–45 mmHg",       "Hypercapnia / Resp acidosis", "Hypocapnia / Resp alkalosis"],
         ["HCO₃⁻",                  "22–26 mEq/L",      "Met. alkalosis",       "Met. acidosis"],
         ["Fasting blood glucose",  "70–100 mg/dL",     "Diabetes (≥126 mg/dL)","Hypoglycaemia (< 70 mg/dL)"],
         ["Serum Creatinine (M)",   "0.7–1.2 mg/dL",    "Renal failure",        "Muscle wasting / low muscle mass"],
         ["BUN",                    "7–20 mg/dL",       "Renal failure / dehydration", "Liver failure, malnutrition"],
         ["Serum Albumin",          "3.5–5.0 g/dL",     "Dehydration",          "Cirrhosis / malnutrition / nephrotic syndrome"],
         ["Total Bilirubin",        "0.2–1.2 mg/dL",    "Jaundice (> 1.2)",     "—"],
         ["Serum Na⁺",             "135–145 mEq/L",     "Hypernatraemia",       "Hyponatraemia (headache, seizures)"],
         ["Serum K⁺",              "3.5–5.0 mEq/L",     "Hyperkalaemia (arrhythmia)", "Hypokalaemia (weakness, cramps)"],
         ["Serum Ca²⁺",            "8.5–10.5 mg/dL",    "Hypercalcaemia (renal stones)", "Hypocalcaemia (tetany, Chvostek)"],
         ["GFR",                    "~125 mL/min",       "—",                    "CKD (< 60 for > 3 months)"],
         ["Vital Capacity",         "~4600 mL",          "—",                    "Restrictive lung disease"],
         ["Tidal Volume",           "~500 mL",           "—",                    "—"],
         ["Pulse rate",             "60–100/min",        "Tachycardia",          "Bradycardia"],
         ["Blood Pressure",         "120/80 mmHg",       "Hypertension (>140/90)","Hypotension (<90/60)"],
         ["Body temperature",       "37°C / 98.6°F",     "Fever (> 38°C)",       "Hypothermia (< 35°C)"]],
        cw=[c1, c2, c3, c4], hbg=NAVY))
    e.append(sp(12))

    e.append(SectionBand("50-QUESTION MOCK TEST – Human Anatomy & Physiology", RED)); e.append(sp(6))
    e.append(box([p("Instructions: 50 MCQs | Represents Section B of the written exam | "
                    "Time: ~22 minutes | No Negative Marking | "
                    "Correct answer marked with ✓", warn)], bg=RED_LT, border=RED))
    e.append(sp(8))

    mcqs = [
        ("1",  "The functional unit of the kidney is:",
         [("Alveolus",False),("Nephron",True),("Villus",False),("Acinus",False)]),
        ("2",  "Which chamber pumps oxygenated blood to the entire body?",
         [("Right atrium",False),("Left atrium",False),("Right ventricle",False),("Left ventricle",True)]),
        ("3",  "Normal adult blood pH:",
         [("6.8–7.0",False),("7.2–7.35",False),("7.35–7.45",True),("7.5–7.8",False)]),
        ("4",  "The pacemaker of the heart is:",
         [("AV node",False),("Bundle of His",False),("SA node",True),("Purkinje fibres",False)]),
        ("5",  "Site of gas exchange in the lungs:",
         [("Bronchi",False),("Trachea",False),("Bronchioles",False),("Alveoli",True)]),
        ("6",  "Which organ produces bile?",
         [("Gallbladder",False),("Pancreas",False),("Liver",True),("Spleen",False)]),
        ("7",  "Normal fasting blood glucose:",
         [("40–60 mg/dL",False),("70–100 mg/dL",True),("120–150 mg/dL",False),("160–200 mg/dL",False)]),
        ("8",  "Hypothalamus regulates:",
         [("Vision",False),("Balance",False),("Body temperature",True),("Hearing",False)]),
        ("9",  "Hormone responsible for 'fight-or-flight' response:",
         [("Insulin",False),("Cortisol",False),("Adrenaline",True),("Glucagon",False)]),
        ("10", "Normal hemoglobin in adult males:",
         [("10–12 g/dL",False),("12–14 g/dL",False),("13–17 g/dL",True),("18–22 g/dL",False)]),
        ("11", "Which enzyme digests starch in the mouth?",
         [("Pepsin",False),("Lipase",False),("Salivary amylase",True),("Trypsin",False)]),
        ("12", "The largest bone in the human body:",
         [("Humerus",False),("Femur",True),("Tibia",False),("Radius",False)]),
        ("13", "Smallest bone in the human body:",
         [("Malleus",False),("Incus",False),("Stapes",True),("Cochlea",False)]),
        ("14", "Total bones in adult human body:",
         [("178",False),("200",False),("206",True),("220",False)]),
        ("15", "ADH acts primarily on which part of the nephron?",
         [("PCT",False),("Loop of Henle",False),("DCT",False),("Collecting duct",True)]),
        ("16", "Secretory IgA is found in:",
         [("Blood serum",False),("Body secretions (milk, saliva, tears)",True),("Bone marrow",False),("CSF",False)]),
        ("17", "Insulin is produced by which cells of the pancreas?",
         [("Alpha cells",False),("Beta cells",True),("Delta cells",False),("Acinar cells",False)]),
        ("18", "Normal platelet count:",
         [("50,000–1,00,000/µL",False),("1,50,000–4,00,000/µL",True),("5,00,000–7,00,000/µL",False),("10,000–50,000/µL",False)]),
        ("19", "Most abundant plasma protein:",
         [("Globulin",False),("Fibrinogen",False),("Albumin",True),("Prothrombin",False)]),
        ("20", "Which part of the brain controls coordination and balance?",
         [("Cerebrum",False),("Thalamus",False),("Hypothalamus",False),("Cerebellum",True)]),
        ("21", "Type II pneumocytes perform which function?",
         [("Gas exchange",False),("Phagocytosis",False),("Surfactant production",True),("Ciliary movement",False)]),
        ("22", "Which hormone is deficient in Diabetes Insipidus?",
         [("Insulin",False),("ADH (Vasopressin)",True),("Aldosterone",False),("Cortisol",False)]),
        ("23", "Normal Tidal Volume:",
         [("150 mL",False),("300 mL",False),("500 mL",True),("1000 mL",False)]),
        ("24", "Vitamin B12 is absorbed in which segment?",
         [("Duodenum",False),("Jejunum",False),("Ileum",True),("Colon",False)]),
        ("25", "Normal WBC count:",
         [("1,000–3,000/µL",False),("4,000–11,000/µL",True),("12,000–15,000/µL",False),("20,000–30,000/µL",False)]),
        ("26", "Haematopoiesis in adults occurs in:",
         [("Liver",False),("Spleen",False),("Yellow bone marrow",False),("Red bone marrow",True)]),
        ("27", "PTH (Parathyroid Hormone) causes:",
         [("Decreased blood calcium",False),("Increased blood calcium",True),("Decreased bone resorption",False),("Increased urinary calcium loss",False)]),
        ("28", "The QRS complex on ECG represents:",
         [("Atrial depolarisation",False),("Atrial repolarisation",False),("Ventricular depolarisation",True),("Ventricular repolarisation",False)]),
        ("29", "Most common type of WBC:",
         [("Lymphocytes",False),("Monocytes",False),("Neutrophils",True),("Eosinophils",False)]),
        ("30", "Surfactant is produced by:",
         [("Type I pneumocytes",False),("Type II pneumocytes",True),("Alveolar macrophages",False),("Club cells",False)]),
        ("31", "Blood-brain barrier is primarily formed by:",
         [("Neurons",False),("Microglia",False),("Astrocytes",True),("Oligodendrocytes",False)]),
        ("32", "IgE is involved in:",
         [("Passive immunity to newborn",False),("ABO blood group reactions",False),("Type I hypersensitivity (allergy/anaphylaxis)",True),("Complement activation",False)]),
        ("33", "Which hormone triggers ovulation?",
         [("FSH",False),("Oestrogen",False),("LH surge",True),("Progesterone",False)]),
        ("34", "Liver stores which vitamins?",
         [("All water-soluble vitamins",False),("Vitamins A, D, E, K and B12",True),("Vitamin C only",False),("Vitamins B1 and B2 only",False)]),
        ("35", "Normal urine output per day:",
         [("500–800 mL",False),("1000–2000 mL",True),("3000–4000 mL",False),("200–400 mL",False)]),
        ("36", "Which antibody crosses the placenta?",
         [("IgA",False),("IgM",False),("IgG",True),("IgE",False)]),
        ("37", "The Bohr effect: increased CO₂/H⁺ causes Hb to:",
         [("Bind O₂ more tightly (curve shifts left)",False),("Release O₂ more easily (curve shifts right)",True),("No change in O₂ affinity",False),("Produce more RBCs",False)]),
        ("38", "Normal GFR (Glomerular Filtration Rate):",
         [("50 mL/min",False),("80 mL/min",False),("125 mL/min",True),("200 mL/min",False)]),
        ("39", "Cardiac muscle has which unique structural feature?",
         [("Voluntary control",False),("Multiple nuclei per cell",False),("Intercalated discs",True),("Non-striated appearance",False)]),
        ("40", "Aldosterone acts primarily on:",
         [("PCT",False),("Loop of Henle",False),("DCT and collecting duct",True),("Bowman's capsule",False)]),
        ("41", "T wave on ECG represents:",
         [("Atrial depolarisation",False),("Ventricular depolarisation",False),("Ventricular repolarisation",True),("SA node firing",False)]),
        ("42", "Heparin is produced by:",
         [("Kupffer cells",False),("Mast cells",True),("Plasma cells",False),("Chief cells",False)]),
        ("43", "Normal respiratory rate in adults:",
         [("5–8/min",False),("12–20/min",True),("25–35/min",False),("40–50/min",False)]),
        ("44", "The right lung has how many lobes?",
         [("2",False),("3",True),("4",False),("5",False)]),
        ("45", "Intrinsic factor is required for absorption of:",
         [("Vitamin C",False),("Iron",False),("Folate",False),("Vitamin B12",True)]),
        ("46", "First antibody produced in primary immune response:",
         [("IgG",False),("IgA",False),("IgM",True),("IgE",False)]),
        ("47", "Blood volume in an average adult:",
         [("2–3 litres",False),("5–6 litres",True),("8–9 litres",False),("10–12 litres",False)]),
        ("48", "The 12th cranial nerve (Hypoglossal) controls:",
         [("Eye movement",False),("Swallowing",False),("Tongue movement",True),("Hearing",False)]),
        ("49", "Which cells in the testes produce testosterone?",
         [("Sertoli cells",False),("Leydig cells",True),("Spermatogonia",False),("Sustentacular cells",False)]),
        ("50", "Normal serum potassium (K⁺):",
         [("1.5–2.5 mEq/L",False),("3.5–5.0 mEq/L",True),("6.0–8.0 mEq/L",False),("9.0–11.0 mEq/L",False)]),
    ]

    half = TW / 2
    for qno, qtext, opts in mcqs:
        e.append(p(f"<b>Q{qno}.</b>  {qtext}", mcq_q))
        # 2×2 grid of options
        row1 = [
            Paragraph(f"A)  {opts[0][0]}", mcq_ok if opts[0][1] else mcq_no),
            Paragraph(f"B)  {opts[1][0]}" + (" ✓" if opts[1][1] else ""), mcq_ok if opts[1][1] else mcq_no),
        ]
        row2 = [
            Paragraph(f"C)  {opts[2][0]}" + (" ✓" if opts[2][1] else ""), mcq_ok if opts[2][1] else mcq_no),
            Paragraph(f"D)  {opts[3][0]}" + (" ✓" if opts[3][1] else ""), mcq_ok if opts[3][1] else mcq_no),
        ]
        opt_tbl = Table([row1, row2], colWidths=[half, half])
        opt_tbl.setStyle(TableStyle([
            ("TOPPADDING",    (0,0), (-1,-1), 1),
            ("BOTTOMPADDING", (0,0), (-1,-1), 1),
            ("LEFTPADDING",   (0,0), (-1,-1), 8),
            ("RIGHTPADDING",  (0,0), (-1,-1), 4),
            ("VALIGN",        (0,0), (-1,-1), "TOP"),
        ]))
        e.append(opt_tbl)
        e.append(sp(3))

    e.append(sp(10))
    e.append(box([
        kl("Correct answers are highlighted in green with ✓ above."),
        p("Target: score 18+ / 25 in this section. Aim for 22+ to be strongly competitive."),
    ], bg=GRN_LT, border=GREEN))
    e.append(sp(18))
    e.append(HRFlowable(width="100%", thickness=1, color=GREY_M))
    e.append(sp(6))
    e.append(p("ASI Lab Technician 2026 – Human Anatomy & Physiology Study Guide | CISF & BSF Paramedical Exam",
               S("FT", fontName="Helvetica-Oblique", fontSize=8, textColor=GREY_M, alignment=TA_CENTER)))
    return e


# ══════════════════════════════════════════════════════════════
# PAGE FOOTER
# ══════════════════════════════════════════════════════════════
def footer(canvas, doc):
    canvas.saveState()
    canvas.setFont("Helvetica", 7.5)
    canvas.setFillColor(GREY_M)
    canvas.drawString(LEFT, 0.55*cm, "ASI Lab Technician 2026 | Human Anatomy & Physiology")
    canvas.drawRightString(A4_W - RIGHT, 0.55*cm, f"Page {doc.page}")
    canvas.setStrokeColor(HexColor("#B0BEC5"))
    canvas.setLineWidth(0.5)
    canvas.line(LEFT, 0.8*cm, A4_W - RIGHT, 0.8*cm)
    canvas.restoreState()


# ══════════════════════════════════════════════════════════════
# BUILD
# ══════════════════════════════════════════════════════════════
def build():
    doc = SimpleDocTemplate(
        OUTPUT, pagesize=A4,
        leftMargin=LEFT, rightMargin=RIGHT,
        topMargin=TOP, bottomMargin=1.6*cm,
        title="ASI Lab Technician – Human Anatomy & Physiology 2026",
        author="Orris",
        subject="CISF BSF ASI Lab Technician Anatomy Physiology Study Guide v2",
    )
    story = []
    for fn in [cover, ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9, ch10]:
        story += fn()

    doc.build(story, onFirstPage=lambda c, d: None, onLaterPages=footer)
    print(f"Done: {OUTPUT}")

build()
Running Command

cd /tmp/workspace/asi-lab-tech-guide && python build_anatomy_v2.py 2>&1

Running Command

ls -lh /tmp/workspace/asi-lab-tech-guide/

Fixed and ready! Here's the corrected PDF:

ASI Human Anatomy Physiology Guide 2026 v2

PDF Document · PDF


What was causing the table collapse — and what I fixed:
ProblemFix Applied
Plain strings in table cells don't word-wrapEvery cell now uses a Paragraph object with wordWrap="LTR"
Column widths didn't add up to page widthAll column width sets now mathematically sum to exactly the usable text width (557 pts)
Overflow text collapsed into neighbouring cellsVALIGN = TOP on all cells so long text grows downward, not sideways
Header cells had no wrapping eitherHeader row uses its own PH() Paragraph style with proper leading
Narrow columns forced text overflowColumns were redesigned per table — narrower for short data (dates, values), wider for descriptions
Every table in all 10 chapters now has proper word-wrap, so no text collapses or overflows.
This is a shared conversation. Sign in to Orris to start your own chat.