Ectopic thyroid tissue

Reading File
Finding Sources
Finding Sources
Searching PubMed

"ectopic thyroid"[MeSH Terms]

Reading File
Reading File
Finding Sources
Loading Image
Loading Image
Loading Image
Reading File
I now have comprehensive, well-sourced material and excellent diagrams. Let me compile the full answer.

Ectopic Thyroid Tissue

Embryological Basis

The thyroid gland originates from the floor of the primitive pharynx during the third week of gestation, at the site of the foramen cecum at the base of the tongue. It then migrates caudally along the thyroglossal duct to its final pretracheal position in the lower neck. Ectopic thyroid results from failure or arrest of this descent at any point along this path.
The transcription factors TTF-1, TTF-2, NKX2-1, FOXE1, and PAX8 orchestrate thyroid gland development; mutations in these genes can cause thyroid dysgenesis, including ectopic positioning.
  • Harrison's Principles of Internal Medicine 22E, p. 3064
  • The Developing Human (Clinically Oriented Embryology), p. 498

Locations

Ectopic thyroid can occur anywhere along the thyroglossal duct tract - from the foramen cecum down to the anterior mediastinum. A second pathway (the thyrothymic tract, from the 3rd pharyngeal pouch) extends inferiorly to the mediastinum.
Sites of ectopic thyroid tissue along the thyroglossal duct tract
Usual sites of ectopic thyroid tissue along the path of the thyroglossal duct. - The Developing Human, p. 498
Midline ectopic thyroid sites and thyrothymic thyroid rests
(A) Common sites for midline ectopic thyroid masses (lingual, sublingual, infrahyoid, prethyroid, isthmus, mediastinal). (B) Major medial and lateral embryological elements including thyrothymic thyroid rests. - Sabiston Textbook of Surgery, p. 1486

Named Locations

SiteNotes
Lingual thyroidMost common ectopic location; at the base of the tongue at the foramen cecum; found in up to 10% of autopsies, clinically relevant in 1/4000
Sublingual thyroidAppears high in the neck at or just inferior to the hyoid bone due to incomplete descent
Infrahyoid / PrethyroidAlong the midline of the neck
Thyroglossal duct remnantThyroid tissue within a persistent thyroglossal duct cyst
Intrathoracic / MediastinalArise from thyroid rests along the thyrothymic tract; can enlarge to form primary intrathoracic goiters
Struma ovariiEctopic thyroid tissue comprising >50% of an ovarian teratoma; rare; can be benign or malignant

Key Clinical Points

1. Lingual Thyroid

  • Presents as a midline mass at the base of the tongue.
  • Often the only thyroid tissue present - in ~70% of ectopic sublingual thyroid cases, no other thyroid tissue exists in the normal cervical position.
  • Can enlarge due to inadequate thyroid hormone production (compensatory TSH stimulation), causing dysphagia, dysphonia, or airway obstruction.
  • Surgical excision may be necessary for compressive symptoms.

2. Sublingual Thyroid

Sublingual thyroid mass and scintigraphy
A sublingual thyroid mass in a child. Tc-99m scintigraphy confirms ectopic sublingual thyroid (asterisk) with no functioning thyroid in the normal anterior neck position. - The Developing Human, p. 499

3. Thyroid Rests (Thyrothymic Tract)

  • Foci of thyroid tissue along the path of thymic descent; found in up to 50% of people and generally not pathological.
  • May be mistaken for pathologic lymph nodes or parathyroid glands.
  • Can be connected to the main gland by a thin stalk or exist as completely separate structures.
  • Enlargement of intrathoracic rests gives rise to primary intrathoracic goiters.

4. Struma Ovarii

  • Part of an ovarian teratoma; can produce thyroid hormone and cause thyrotoxicosis with low radioiodine uptake in the neck.
  • Listed alongside thyrotoxicosis factitia and iodine excess as a cause of thyrotoxicosis with low/absent thyroidal radionuclide uptake on scan.

Diagnosis

  • Ultrasound is the first-line investigation, especially to confirm the absence of normal cervical thyroid tissue.
  • Tc-99m pertechnetate scintigraphy confirms functional ectopic tissue and is essential before any surgical excision to avoid removing the patient's only functioning thyroid tissue.
  • CT/MRI for deeper or mediastinal locations.
Critical point: It is essential to differentiate ectopic thyroid from a thyroglossal duct cyst before surgery. Inadvertent removal of the only functioning thyroid tissue will render the patient permanently hypothyroid and dependent on lifelong thyroid hormone replacement.

Complications and Associations

  • Congenital hypothyroidism - ectopic thyroid is a leading cause; ectopic glands are often insufficient producers of thyroid hormone, triggering compensatory goitrous enlargement under elevated TSH.
  • Malignant transformation - thyroid cancers (papillary carcinoma most common) can arise in ectopic thyroid tissue including lingual thyroid and struma ovarii.
  • Thyrotoxicosis - rarely, from hyperfunctioning ectopic tissue (struma ovarii, functional teratomas).

Sources:
  • The Developing Human: Clinically Oriented Embryology, pp. 498-499
  • Sabiston Textbook of Surgery, pp. 1485-1486
  • Harrison's Principles of Internal Medicine, 22E, p. 3064
  • Cummings Otolaryngology, Head and Neck Surgery
  • Mulholland and Greenfield's Surgery, 7th ed.

Retrosternal goiter

Finding Sources
Finding Sources
Searching PubMed

"retrosternal goiter" AND surgery

Finding Sources
Finding Sources
Reading Article

PMID: 40567093

Reading File
Reading File
Reading File
Reading File
Loading Image
Finding Sources
Reading File
Reading File
Loading Image
Loading Image
Reading File
I now have comprehensive material. Let me compile the complete answer.

Retrosternal Goiter

Also called substernal, intrathoracic, or diving goiter - these are terms used interchangeably, though "retrosternal" strictly refers to goiters behind the sternum while "intrathoracic" denotes at least 50% of thyroid tissue located below the thoracic inlet. It affects less than 1% of all goiter patients.

Classification

1. Secondary (Cervical Extension) - ~99%

The vast majority arise from downward extension of a cervical multinodular goiter along the fascial planes of the neck, drawn by gravity and negative intrathoracic pressure. These maintain their blood supply from the superior and inferior thyroid arteries (cervical vessels).

2. Primary (True Intrathoracic) - ~1%

Arise from ectopic accessory thyroid tissue within the chest, with no connection to cervical thyroid. They are supplied by intrathoracic blood vessels (internal mammary, innominate, or aortic branches). These are more likely to require a thoracic approach.
  • Schwartz's Principles of Surgery, 11th ed. | Sabiston Textbook of Surgery

Clinical Presentation

About 40% can be asymptomatic, presenting as an incidental finding on chest X-ray or CT.
When symptomatic:
SymptomMechanism
Dyspnea / airway obstructionTracheal compression (most common; acute distress in up to 20%)
DysphagiaEsophageal compression
StridorFixed tracheal narrowing (worse on exertion)
HoarsenessRecurrent laryngeal nerve compression
SVC syndromeVenous distension of neck/chest wall, facial oedema, plethora, cyanosis, papilloedema
Horner's syndromeSympathetic chain compression
ChylothoraxThoracic duct compression
TIAsThyrocervical steal

Pemberton's Sign

Raising both arms above the head causes facial congestion, cyanosis, and respiratory distress due to functional obstruction of the thoracic inlet by the goiter. This is a classic clinical sign of increased thoracic inlet pressure.
  • Scott-Brown's Otorhinolaryngology, Head & Neck Surgery, p. 868

Investigations

Chest X-Ray

The classic finding is a superior mediastinal mass with tracheal deviation or compression, often discovered incidentally.
Chest X-ray showing mediastinal mass from primary intrathoracic goiter
CXR: incidental finding of a mediastinal mass due to primary intrathoracic goiter. - Scott-Brown's, p. 868

CT Scan (Investigation of Choice)

The most important preoperative investigation. Key features to document:
  • Full inferior extent of the intrathoracic component (scan from skull base to carina)
  • Mediastinal compartment - anterior vs. posterior (posterior location increases the chance of lateral thoracotomy)
  • Tracheal deviation and compression - degree and level
  • Relationship to great vessels (innominate, SVC, aortic arch)
  • Evidence of malignancy (extracapsular extension)
CT findings that predict sternotomy: extension below the aortic arch, evidence of extra-thyroid extension suggesting malignancy, posterior mediastinal location, or primary intrathoracic goiter.
For substernal goiter evaluation, non-contrast CT is sufficient. IV contrast is added only if malignancy is suspected.
CT showing left substernal goiter with tracheal compression and deviation
CT scan: (A) Left-sided substernal goiter extending into the posterior mediastinum with tracheal compression and deviation. (B) Contrast CT showing locally advanced follicular thyroid cancer with tracheal wall and esophageal invasion. - Sabiston Textbook of Surgery, p. 1494

Thyroid Function Tests

  • Majority are euthyroid (80%)
  • Up to 30% may have subclinical thyrotoxicosis (suppressed TSH with normal T3/T4)
  • Overt hyperthyroidism is less common

Ultrasound

Cannot evaluate the intrathoracic component. Useful only for cervical thyroid morphology.

Scintigraphy

  • Plays no role in the preoperative evaluation of biochemically euthyroid patients
  • Intrathoracic goiters often demonstrate limited iodine avidity despite large size
  • May be useful when ectopic functioning tissue is suspected as a cause of thyrotoxicosis

Pulmonary Function Tests

Objective assessment of respiratory compromise - flow-volume loops may demonstrate a fixed extrathoracic or variable intrathoracic obstruction pattern.

Risk of Malignancy

Reported in up to 11% of goiters with intrathoracic extension - FNA where accessible.

Management

Indications for Surgery

  • Significant airway compression
  • Symptomatic patients (dysphagia, dyspnoea)
  • Young patients in whom symptoms are likely to develop
  • Suspected or confirmed malignancy
In elderly patients with incidentally discovered retrosternal goiters and no symptoms, most surgeons favour observation rather than prophylactic surgery, balancing operative risk against benefit.

Surgical Approach

Transcervical (Collar) Incision - >95% of cases

The standard and most common approach. Key steps:
  1. Ligate and divide superior pole vessels and middle thyroid veins first
  2. Divide the isthmus early to allow independent mobilization of each lobe
  3. Blunt finger dissection along the thyroid capsule to free fascial attachments
  4. Large 1-0 or 2-0 sutures placed deep into the goiter to facilitate traction and delivery through the neck
  5. Ligamentous tissue between the sternal heads of the clavicles may be gently divided to increase the opening

Median Sternotomy - Indications (~5%)

Required in:
  • Invasive thyroid malignancy
  • Previous thyroid surgery (risk of parasitic mediastinal vessels from prior operations)
  • Primary intrathoracic goiter with no cervical thyroid tissue
  • Posterior mediastinal extension (may require lateral thoracotomy instead)
  • Goiter too large to deliver through the cervical incision
Incisions for partial sternotomy - collar incision extended with midline sternal split to the 3rd intercostal space
Incisions for partial sternotomy: collar incision combined with midline sternal division to the 3rd intercostal space, then laterally at the 3rd-4th intercostal space. - Schwartz's Principles of Surgery
The chest should be prepared and draped in all cases of substernal goiter surgery in the event emergency sternotomy is needed to control mediastinal bleeding or remove an unexpectedly invasive cancer.

Complications of Surgery

  • Recurrent laryngeal nerve injury - risk is increased due to altered anatomy and limited visibility
  • Hypoparathyroidism - parathyroids may be adherent or displaced
  • Tracheomalacia - softening of tracheal rings from chronic compression; may cause airway collapse post-extubation ("tracheal kiss") - requires awake extubation planning
  • Mediastinal haemorrhage
  • Chylothorax

Recent Evidence (2025)

A 2025 systematic review (Miani et al., Acta Otorhinolaryngol Ital, PMID: 40567093) covering 93 articles confirms that transcervical excision remains the most common approach for intrathoracic goiters, while transthoracic approaches must always be planned for. Surgery should be performed at specialist centres with experienced multidisciplinary teams to minimize complications.
A concurrent 2025 systematic review and meta-analysis (Alqutub et al., J Surg Res, PMID: 40850248) specifically examined predictors of sternotomy in substernal goiter - the key factors identified include posterior mediastinal extension, primary intrathoracic location, prior neck surgery, and goiter extension below the aortic arch.

Sources:
  • Sabiston Textbook of Surgery, pp. 1485-1494
  • Schwartz's Principles of Surgery, 11th ed., pp. 1083-1092
  • Bailey and Love's Short Practice of Surgery, 28th ed., pp. 882, 5211-5224
  • Scott-Brown's Otorhinolaryngology, Head & Neck Surgery, pp. 867-869
  • Cummings Otolaryngology, Head and Neck Surgery, p. 220

Thyroid swelling or case btao pura cover the viva qsn

Finding Sources
Finding Sources
Finding Sources
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
I have enough from what I've already retrieved - S Das classification and clinical details (lines 3339-3735), plus the Sabiston and Bailey & Love material from earlier sessions. Let me now compile a comprehensive viva-format answer using all the textbook content collected.

Thyroid Swelling - Complete Surgical Viva Guide


1. HOW DO YOU RECOGNIZE A THYROID SWELLING?

"A thyroid swelling is recognized by its position, its shape, and by the fact that it moves upwards during deglutition."
  • S Das, A Manual on Clinical Surgery
Why does it move on swallowing? Because the thyroid gland is enclosed within the pretracheal fascia, which is attached to the larynx and trachea - these structures move upward during swallowing, carrying the thyroid with them.
Exception (viva trap): Very large, fixed malignant thyroid masses may NOT move on swallowing because they have infiltrated surrounding structures.
Other swellings that move on swallowing: Thyroglossal cyst, subhyoid bursitis. Malignant/tuberculous lymph nodes fixed to trachea may also move.
Thyroglossal cyst vs thyroid swelling: A thyroglossal cyst moves up additionally when the tongue is protruded (because of its attachment to the foramen cecum via the thyroglossal tract). A thyroid swelling does NOT move on tongue protrusion.

2. CLASSIFICATION OF THYROID SWELLINGS (Das Classification)

(a) Non-toxic (Simple) Goitre
  1. Diffuse parenchymatous (hyperplastic)
  2. Colloid goitre
  3. Multinodular goitre
  4. Solitary nodular goitre
(b) Toxic Goitre
  1. Diffuse toxic - Graves' Disease (Primary thyrotoxicosis)
  2. Toxic multinodular goitre (Secondary thyrotoxicosis)
  3. Toxic adenoma (Plummer's disease - Tertiary/solitary toxic nodule)
(c) Neoplastic
  1. Benign - Follicular adenoma
  2. Malignant - Papillary, Follicular, Medullary, Anaplastic, Lymphoma
(d) Thyroiditis
  1. Acute bacterial (suppurative)
  2. Granulomatous (de Quervain's / subacute)
  3. Autoimmune - Hashimoto's (lymphocytic)
  4. Riedel's (fibrous / woody thyroiditis)
  5. Chronic bacterial (TB, syphilis)
(e) Other rare - Amyloid goitre, etc.

3. HISTORY TAKING

Presenting Complaint

  • Duration of swelling (long history = benign; rapidly growing = malignant or anaplastic)
  • Mode of onset: sudden increase in size suggests haemorrhage into a nodule
  • Pain: usually absent; pain suggests thyroiditis, acute suppurative, or haemorrhage
  • Rate of growth

Symptoms of Pressure (Compressive symptoms)

  • Dysphagia - esophageal compression
  • Dyspnoea / stridor - tracheal compression
  • Hoarseness of voice - RLN involvement (DANGER sign - suggests malignancy)
  • Venous engorgement - SVC / neck vein compression

Symptoms of Thyroid Dysfunction

Hyperthyroidism: Palpitations, weight loss despite good appetite, heat intolerance, excessive sweating, tremor, diarrhea, irritability, oligomenorrhea
Hypothyroidism: Weight gain, cold intolerance, constipation, lethargy, dry skin, hair loss, menorrhagia, bradycardia

Relevant History

  • Endemic area? (Iodine deficiency)
  • Goitrogenic diet - cabbage, cauliflower, brassica family, soya
  • Antithyroid drugs / lithium / amiodarone
  • Radiation exposure (neck irradiation in childhood - risk of papillary Ca)
  • Family history - MEN 2A/2B (medullary thyroid Ca), familial papillary Ca
  • Age and sex - female:male = 6:1 for goitre; males have higher risk of malignancy in a thyroid nodule
  • Pregnancy / puberty - physiological goitre

4. EXAMINATION - SYSTEMATIC APPROACH

Expose Patient Properly

Neck exposed down to the nipple level; collar removed; patient seated with neck slightly extended.

General Examination

Look for signs of thyroid dysfunction:
FeatureHyperthyroidHypothyroid
BuiltThinObese/puffy
SkinWarm, moist, velvetyDry, coarse, cold
HairFine, thinningCoarse, thin, brittle
PulseTachycardia, AFBradycardia
EyesExophthalmos, lid lag, lid retractionPeriorbital puffiness
HandsTremor, palmar erythemaDry, cold
ReflexesBriskSlow-relaxing
Specific eye signs (Graves' Disease):
  • Exophthalmos (proptosis) - due to retroorbital infiltration
  • Lid lag (von Graefe's sign) - upper lid lags behind descending eyeball
  • Lid retraction (Dalrymple's sign) - sclera visible above iris
  • Infrequent blinking (Stellwag's sign)
  • Convergence weakness (Moebius sign)
  • Joffroy's sign - absent forehead wrinkling when looking up

Local Examination of the Thyroid

INSPECTION (stand in front, then side)

Note:
  1. Site - midline vs lateral
  2. Size - rough estimate
  3. Shape - diffuse vs nodular
  4. Number of swellings - solitary vs multiple nodules
  5. Surface - smooth vs nodular
  6. Skin - normal / red (inflammation) / dilated veins / fixation
  7. Symmetry - which lobe is more enlarged
  8. Visible pulsation - thyrotoxic goitre may pulsate
  9. Move on swallowing - ask patient to swallow water; watch the swelling

PALPATION (stand behind the patient)

Ask patient to slightly flex the neck (relaxes sternomastoid).
Note:
  1. Temperature - warm in thyroiditis, normal in simple goitre
  2. Tenderness - present in thyroiditis, haemorrhage into nodule
  3. Size and extent - measure lobes; feel for substernal extension (lower border not felt = retrosternal)
  4. Surface - smooth vs nodular
  5. Consistency:
    • Soft/elastic = colloid goitre, simple goitre
    • Firm = adenoma, multinodular
    • Hard/stony = malignancy (papillary, anaplastic), calcification, Riedel's
    • Rubbery/firm = Hashimoto's (like cartilage), lymphoma
    • Cystic = colloid cyst, haemorrhage, thyroglossal cyst
  6. Mobility - freely mobile vs fixed (fixation = malignancy)
  7. Confirmation of movement on swallowing
  8. Carotid pulsation - "Berry's sign": in malignant goitre, the carotid pulsation is absent on the affected side because the malignant thyroid mass envelops the carotid artery
  9. Cervical lymph nodes - palpate all groups; enlarged nodes = malignancy / Hashimoto's

PERCUSSION

  • Percuss over the manubrium sterni - dull note indicates retrosternal extension

AUSCULTATION

  • Bruit over the thyroid = hypervascular gland (Graves' disease, thyrotoxicosis)
  • Must differentiate from a carotid bruit (heard in the neck, not directly over the gland)

PEMBERTON'S SIGN

Ask patient to raise both arms above the head. Positive = facial congestion, cyanosis, elevation of JVP, respiratory distress. Indicates functional obstruction of the thoracic inlet - suggests retrosternal goitre.

KOCHER'S TEST (Tracheal Compression Test)

Gently compress the thyroid laterally with fingers. Positive = stridor produced, indicating tracheal compression (narrowed trachea).

5. FEATURES SUGGESTING MALIGNANCY (Viva Favourite!)

FeatureSignificance
Stony hard consistencyPapillary Ca, anaplastic, calcification
Rapid growthAnaplastic carcinoma
HoarsenessRLN involvement
Fixation to surrounding structuresInvasion by malignancy
Dysphagia (late)Esophageal invasion
Cervical lymphadenopathyNodal metastases (especially papillary Ca - bilateral nodes)
Berry's signCarotid enveloped by malignant mass
Male patient with solitary noduleHigher malignancy risk
Children with noduleHigher malignancy risk (~50%)
History of neck irradiationPapillary Ca
Solitary nodule (vs multinodular)Relatively higher risk of malignancy

6. INVESTIGATIONS

Biochemical

  1. Serum T3, T4, TSH - essential to determine functional status
    • TSH low + T3/T4 high = hyperthyroid
    • TSH high + T3/T4 low = hypothyroid
    • TSH suppressed with normal T3/T4 = subclinical hyperthyroidism
  2. Thyroid antibodies:
    • Anti-TPO antibody - Hashimoto's (>95%)
    • Anti-TSH receptor (TRAb / TSIG) - Graves' disease
    • Anti-thyroglobulin antibody
  3. Serum calcitonin - if medullary thyroid carcinoma suspected (MEN 2)
  4. Serum thyroglobulin - tumour marker for differentiated thyroid cancer (post-thyroidectomy surveillance)
  5. Serum calcium - pre-operatively (parathyroid function)

Imaging

InvestigationWhen/Why
Ultrasound neckFirst-line for all thyroid swellings; size, cystic vs solid, nodule characteristics (TIRADS)
FNAC (Fine Needle Aspiration Cytology)Gold standard investigation for a thyroid nodule; Bethesda system reporting
Radioisotope scan (Tc-99m or I-123)Hot/warm/cold nodule characterization; ectopic thyroid; post-thyroidectomy remnant
CT neck + chestRetrosternal extension; tracheal compression; malignancy staging
MRISame as CT without radiation; good for soft tissue detail
X-ray chestTracheal deviation, mediastinal widening, retrosternal goitre
X-ray neckTracheal deviation; soft tissue calcification (papillary Ca - psammoma bodies)
LaryngoscopyPre-op assessment of vocal cord mobility; if hoarseness present

FNAC - Bethesda System

CategoryRisk of MalignancyManagement
I - Non-diagnostic-Repeat FNAC
II - Benign<3%Observe
III - AUS/FLUS~10-30%Repeat / molecular testing
IV - Follicular neoplasm25-40%Hemithyroidectomy
V - Suspicious for malignancy60-75%Near-total/total thyroidectomy
VI - Malignant>97%Surgery
Viva trap: FNAC cannot distinguish follicular adenoma from follicular carcinoma - this requires histology (capsular and vascular invasion). Hence Category IV requires diagnostic hemithyroidectomy.

Radioisotope Scan

  • Hot nodule = increased uptake = functioning = almost never malignant (Toxic adenoma)
  • Cold nodule = decreased uptake = non-functioning = 10-15% chance of malignancy
  • Warm nodule = same uptake as rest of gland

7. DIFFERENTIAL DIAGNOSIS OF A MIDLINE NECK SWELLING

ConditionKey Features
Thyroid swellingMoves on swallowing; does NOT move on tongue protrusion
Thyroglossal cystMidline; moves on swallowing AND tongue protrusion; usually subhyoid
Subhyoid bursitisMidline; moves on swallowing; rare
LipomaDoes not move on swallowing; soft; lobulated
Dermoid cystMidline; tense; does not move on swallowing
Lymph nodeLateral usually; does not move on swallowing unless fixed to trachea

8. MANAGEMENT OVERVIEW

Indications for Surgery in Goitre

  1. Pressure symptoms - dyspnoea, dysphagia, stridor
  2. Cosmetic disfigurement
  3. Suspected or confirmed malignancy
  4. Retrosternal extension
  5. Toxic goitre failing medical management or not suitable for RAI
  6. Failure to respond to medical treatment

Types of Surgery

ProcedureIndication
Hemithyroidectomy (lobectomy + isthmusectomy)Solitary nodule (diagnostic or therapeutic), Bethesda IV, unilateral disease
Near-total thyroidectomyMost thyroid cancers, bilateral disease
Total thyroidectomyDifferentiated thyroid cancer >1 cm, medullary thyroid Ca, Graves' disease (surgical option)
Subtotal thyroidectomyGraves' disease (historical), bilateral toxic MNG
Hartley-Dunhill operationOne lobe + partial contralateral = for bilateral MNG

Medical Management

  • Antithyroid drugs: Carbimazole, propylthiouracil (PTU)
  • Beta-blockers: Propranolol - control symptoms (palpitations, tremor) rapidly
  • Iodine (Lugol's): Pre-op in Graves' to reduce vascularity
  • Radioactive Iodine (I-131): Graves' disease, toxic MNG (not in pregnancy/children)
  • Thyroxine: Hypothyroidism post-thyroidectomy; also used to suppress TSH in differentiated Ca
  • Iodine supplementation: Endemic goitre prevention and treatment

9. COMPLICATIONS OF THYROIDECTOMY (Classic Viva Topic)

Immediate (0-24 hrs)

ComplicationMechanismFeature
Reactionary haemorrhageSlipped ligatureNeck swelling, stridor, cyanosis
Respiratory obstructionHaemorrhage compressing tracheaEmergency - open wound at bedside
Thyroid stormExcess hormone releaseHyperpyrexia, tachycardia, agitation
RLN injury (unilateral)Nerve cut/stretchedHoarseness
RLN injury (bilateral)Both nerves cutAphonia, stridor - re-intubation needed

Early (24 hrs - 1 week)

ComplicationMechanismFeature
HypoparathyroidismParathyroids removed/devascularizedHypocalcaemia → tetany; Chvostek's, Trousseau's signs
Wound infection
TracheomalaciaChronic pressure on tracheal ringsPost-extubation stridor - "tracheal kiss"

Late

Complication
HypothyroidismAfter total/near-total thyroidectomy → lifelong thyroxine
Recurrence of goitre / toxicityAfter subtotal thyroidectomy
Keloid scar
Hypoparathyroidism (permanent)1-3% after total thyroidectomy
Voice change (external laryngeal nerve)Loss of high-pitched notes, voice fatigue
Viva trap - "Bed-side emergency kit": Every patient post-thyroidectomy must have a stitch-cutter or clip remover at the bedside to open the wound in emergency to evacuate haematoma.

10. HIGH-YIELD VIVA QUESTIONS & ANSWERS

Q: Why does thyroid swelling move on swallowing? A: The thyroid is enclosed within the pretracheal fascia, which is attached to the trachea and larynx. On swallowing, these structures elevate, carrying the thyroid with them.
Q: What is the difference between primary, secondary, and tertiary thyrotoxicosis?
  • Primary = Graves' disease (diffuse toxic goitre) - de novo autoimmune
  • Secondary = Toxic multinodular goitre - pre-existing MNG becomes toxic
  • Tertiary = Solitary toxic adenoma (Plummer's disease)
Q: FNAC cannot differentiate follicular adenoma from carcinoma. Why? A: Because the distinction requires histological evidence of capsular invasion or vascular invasion, which cannot be assessed on fine needle aspirate cytology.
Q: What is a "cold nodule" and what is its significance? A: A nodule with decreased radionuclide uptake on scintigraphy. Non-functioning. About 10-15% of cold nodules are malignant - hence all cold nodules require FNAC.
Q: What is Berry's sign? A: Absence of carotid pulsation on the side of the thyroid swelling, indicating that the malignant thyroid mass has encircled/enveloped the carotid artery. Strong indicator of malignancy and inoperability.
Q: What is Pemberton's sign? A: Raising both arms above the head causes facial congestion, cyanosis, elevation of JVP and respiratory distress - indicates a retrosternal goitre causing functional obstruction of the thoracic inlet.
Q: What is Kocher's test? A: Lateral compression of the goitre produces stridor - indicates significant tracheal compression.
Q: The most common thyroid cancer is...? A: Papillary carcinoma (~80%). Spreads via lymphatics. Good prognosis. Associated with Psammoma bodies (calcification), radiation exposure, RET/PTC mutations.
Q: Which thyroid cancer has the WORST prognosis? A: Anaplastic carcinoma - median survival ~3-6 months. Usually occurs in elderly. Very rapidly growing, rock-hard mass.
Q: Which thyroid cancer is a marker of MEN syndrome? A: Medullary thyroid carcinoma - associated with MEN 2A (with phaeochromocytoma + hyperparathyroidism) and MEN 2B (with phaeochromocytoma + mucosal neuromas + marfanoid habitus). RET proto-oncogene mutation.
Q: Pre-operative preparation for Graves' disease thyroidectomy? A: (1) Render euthyroid with antithyroid drugs (carbimazole) over 6-8 weeks. (2) Give Lugol's iodine (potassium iodide) for 10-14 days pre-op to reduce gland vascularity and firmness. (3) Propranolol to control sympathetic symptoms.
Q: What is the Hartley-Dunhill operation? A: Total removal of one lobe + isthmus + subtotal removal of the other lobe. Used for bilateral multinodular goitre - balances the risk of recurrence vs hypothyroidism.

Sources: S Das - A Manual on Clinical Surgery 13th ed. | Bailey & Love's Short Practice of Surgery 28th ed. | Sabiston Textbook of Surgery | Schwartz's Principles of Surgery 11th ed. | Harrison's Principles of Internal Medicine 22E

Brest topic in surgery cover the history taking , examination point,and other viva qsn

Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Loading Image
Loading Image
Loading Image

Breast - Complete Surgical Viva Guide


1. HISTORY TAKING

Patient Details

  • Age - single most important demographic factor:
    • <35 yrs: Fibroadenoma most likely
    • 20-40 yrs: Fibroadenosis (mammary dysplasia)
    • 40 yrs: Carcinoma must always be excluded
    • Young lactating woman: Mastitis / breast abscess
  • Sex - rare but carcinoma in males is possible
  • Residence - carcinoma + fibroadenosis more common in western world; rare in Japan
  • Parity / Social status - nulliparous women have higher risk of carcinoma and fibroadenosis; breastfeeding is protective

Chief Complaint

1. Lump (most common presenting complaint)
  • Mode of onset, duration
  • Rate of growth: slow + long history = benign; fast + short history = likely malignant
  • Sudden enlargement: haemorrhage into a cyst or nodule
  • Note: average time between patient discovering a breast lump and reporting to a surgeon is ~6 weeks in carcinoma
2. Pain (mastalgia)
"Carcinoma of the breast is a painless condition." - S Das
Pain typeDiagnosis
Throbbing, severeAcute mastitis / abscess (pus formation)
Cyclical, worse before periodsFibroadenosis (most common benign cause)
Non-cyclical, localizedPeriductal mastitis, fat necrosis
Back / hip / shoulder pain (late)Bony metastases from carcinoma
Painless lump accidentally feltMust rule out carcinoma
3. Nipple Discharge
Discharge colourDiagnosis
Bright red / bloodDuct papilloma (most common), duct carcinoma
Serous / clearDuct papilloma, early carcinoma
Green / brownFibroadenosis (duct ectasia)
White (milk)Galactorrhoea (prolactinoma, drugs)
PurulentAbscess, infected duct ectasia
4. Nipple changes
  • Retraction / inversion - recent onset = malignancy; lifelong = normal variant
  • Eczema / scaling of nipple = Paget's disease of nipple (must exclude underlying ductal carcinoma)
  • Ulceration
5. Skin changes - redness, dimpling, peau d'orange, ulceration, satellite nodules
6. Axillary swelling - may indicate nodal metastases

Past History

  • Previous breast lumps, biopsies, operations
  • History of chest wall irradiation (risk factor for breast cancer)
  • Hormone use - OCP, HRT (risk factors)
  • Previous carcinoma of the opposite breast or endometrium

Menstrual & Obstetric History

  • Menarche age (early menarche = risk factor)
  • Menopause age (late menopause = risk factor)
  • Pregnancies: nulliparity or first child after 30 = risk factor
  • Breastfeeding: protective
  • Last menstrual period

Family History

  • First-degree relative (mother, sister) with breast cancer = 2-3x increased risk
  • BRCA1 / BRCA2 mutations (ask for family history of ovarian cancer too)
  • Bilateral or early-onset (<50 yrs) breast cancer in family = high risk

Drug History

  • OCP, HRT (slight increased risk)
  • Phenothiazines, metoclopramide, domperidone → galactorrhoea
  • Tamoxifen (if currently being treated)

2. EXAMINATION - SYSTEMATIC APPROACH

General Examination

  • Build, weight loss (late cancer)
  • Pallor, jaundice (liver metastases)
  • Lymphoedema of the arm (post-surgery or nodal blockage)
  • Lumbar spine / hip tenderness (bone metastases)
  • Hepatomegaly (liver metastases)
  • Signs of pleural effusion (lung metastases)

LOCAL EXAMINATION

Setup

  • Patient seated facing examiner, fully exposed to the nipple level
  • Adequate privacy; chaperone
  • Examine normal breast first, then compare with affected side

INSPECTION (4 positions)

Position 1: Arms by the side (at rest) Note:
  1. Symmetry of both breasts - any size difference
  2. Contour and shape - any flattening, bulge, distortion
  3. Skin changes:
    • Redness / erythema = mastitis, inflammatory carcinoma
    • Peau d'orange = skin oedema with pitting, deepening of sweat gland openings - classic sign of carcinoma (lymphatic blockage by cancer cells)
    • Dimpling / puckering = invasion of Cooper's ligaments by carcinoma
    • Dilated superficial veins = cystosarcoma phylloides, rapidly growing sarcoma, acute duct obstruction
    • Ulceration / fungation = advanced carcinoma
    • Skin nodules = satellite / metastatic skin deposits
  4. Nipple position, level, symmetry
    • Retraction (recent = malignant; central mass pulling nipple)
    • Deviation / asymmetry
    • Ulceration / eczema = Paget's disease
  5. Axillae - visible swelling, skin puckering
Peau d'orange - classic sign of breast carcinoma with oedematous skin and deepened pores
Peau d'orange - oedema of the skin of the breast with deepening of the sweat gland mouths, due to blockage of subcuticular lymphatics by cancer cells. - S Das Clinical Surgery
Nipple retraction due to breast carcinoma
Nipple retraction caused by deep carcinoma pulling along the lactiferous ducts via fibrosis - S Das
Position 2: Arms raised above the head
  • Reveals the lower surfaces of both breasts
  • Brings out lumps, puckering and distortion not visible at rest
  • Inspect the submammary fold (lift breast if needed)
  • Inspect axillae for swelling and ulceration
Position 3: Hands pressed on hips (pectoral contraction)
  • Tenses the pectoralis major
  • Accentuates dimpling / tethering if present (Cooper's ligament invasion)
  • Any change in contour with muscle contraction
Position 4: Leaning forward
  • Pendulous breasts fall forward - reveals asymmetry and skin changes on undersurface

PALPATION

Patient position: Start in sitting, then semi-recumbent (45°), then lying supine with a small pillow under the scapula of the side being examined (prevents breast falling laterally).
Technique:
  • Use the palmar surface of the fingers with the hand flat (NOT the palm of hand, NOT fingertips)
  • Palpate between pulps of fingers and thumb to examine a lump
  • Always palpate the normal breast first to know the baseline texture

Quadrant Examination

Systematically palpate all four quadrants:
  • Upper outer (UOQ) - most common site of carcinoma (50%)
  • Upper inner
  • Lower outer
  • Lower inner
  • Retroareolar region (just behind the nipple - easy to miss!)
  • Axillary tail of Spence

On Finding a Lump - Assess All These Features:

1. Site / Position
  • Quadrant + distance from nipple
  • UOQ is most common; retroareolar is often missed
2. Size and Shape
  • Measure in cm
  • Globular = fibroadenoma
  • Irregular = carcinoma
3. Number
  • Solitary: fibroadenoma, cyst, carcinoma
  • Multiple bilateral: fibroadenosis
4. Surface
  • Smooth = fibroadenoma, cyst
  • Irregular / nodular = carcinoma, fibroadenosis
5. Edge / Margin
  • Well-defined = fibroadenoma, cyst
  • Ill-defined / spiculated = carcinoma
6. Consistency
ConsistencyDiagnosis
Soft, cysticBreast cyst, abscess
Firm, India-rubber / diffuseFibroadenosis
Firm, well-encapsulatedFibroadenoma
Stony hard, irregularCarcinoma
Varies (soft to hard)Sarcoma / cystosarcoma phylloides
7. Fluctuation - test for cystic swellings (cyst, abscess)
8. Transillumination - in dark room; cyst = translucent; solid tumour = opaque; fat = translucent
9. Tenderness - mastitis, abscess; absent in carcinoma (painless)
10. Fixity to Skin - Three levels:
(i) Tethering to skin: Invasion of Cooper's ligaments (fibrous septae from gland to skin). The lump can still be moved slightly but at the extremes of movement, skin dimples.
  • Test: move lump side to side - skin dimples at extremes = tethered
(ii) Fixed to skin: Direct infiltration of skin by tumour. Lump cannot be moved independent of skin. Overlying skin cannot be pinched up.
(iii) Note: Any tumour deep to the nipple will be fixed to the nipple (benign or malignant) because the main lactiferous ducts pass through it.
11. Fixity to Breast Tissue
  • Fibroadenoma: freely mobile within breast substance = "Breast Mouse" / "Floating Tumour"
  • Carcinoma: fixed to breast tissue; fibrous strands radiating from mass
12. Fixity to Pectoralis Major
  • Ask patient to press her hand on her hip lightly (muscle relaxed) - test lump mobility
  • Now ask her to press hip as hard as she can (muscle taut) - retest mobility
  • Reduced mobility in the line of muscle fibres = fixed to pectoralis major or pectoral fascia
Testing fixity of breast lump to pectoralis major by tightening the muscle
Testing lump fixity to pectoralis major - patient presses hip to tighten muscle, then lump mobility is reassessed in direction of muscle fibres. - S Das
13. Fixity to Serratus Anterior
  • Lower outer quadrant lumps may fix to serratus anterior
  • Test: ask patient to push against a wall with outstretched hand of affected side - fixed lump barely moves
14. Fixity to Chest Wall
  • Lump restricted in ALL directions irrespective of any muscle contraction = fixed to chest wall (T4 carcinoma)
15. Nipple Palpation
  • Feel tissue just behind the nipple
  • Press the lump behind the nipple - note if this expresses discharge
  • Colour of discharge (see above)
  • From single duct (papilloma) or multiple ducts (fibrocystic)
16. Axillary Examination Patient's arm supported by examiner's ipsilateral hand (relaxing pectoralis) Palpate all groups:
  • Anterior (pectoral) nodes - most commonly first involved in breast cancer
  • Central nodes
  • Posterior (subscapular) nodes
  • Lateral (brachial) nodes
  • Apical nodes (infraclavicular)
Note: Size, number, consistency, mobility, tenderness of any palpable nodes
17. Supraclavicular Nodes
  • Feel in the angle between the clavicle and sternomastoid from behind
  • Enlarged = advanced (N3) disease
18. Opposite Breast and Axilla - must always be examined

3. DIFFERENTIAL DIAGNOSIS OF A BREAST LUMP

ConditionAgeConsistencyMobilityTenderSkin/NippleOther
Fibroadenoma15-35Firm, smoothHighly mobile ("breast mouse")NoNormalWell-defined, no nodes
Breast cyst30-55Cystic/fluctuantMobileNoNormalTransilluminates; may refill
FibroadenosisAny (20-50)Firm, diffuse, nodularDiffuse bilateralYes (cyclical)NormalMultiple lumps
Carcinoma>40Stony hardFixed to breast tissueNoPeau d'orange, dimplingHard nodes, nipple retraction
AbscessLactatingFluctuantFixed (inflamed)Very tenderRed, warmFever, raised WBC
Fat necrosisAny (post-trauma)Hard, irregularMay be fixed±Skin tethering possibleHistory of trauma
Cystosarcoma phylloides>40Varies; hugeMobile (initially)NoDilated veins; not fixedRapidly growing, giant tumour
Duct papilloma>30Cystic near areolaMobileNoBloody nipple dischargeRetroareolar
Paget's disease>50Underlying mass-NoEczema of nippleRepresents underlying DCIS/Ca
Gynaecomastia (male)AnyFirm discCentralTenderNormalBilateral rubbery disc

4. TRIPLE ASSESSMENT (The Standard for any Breast Lump)

The gold standard is Triple Assessment - all three must be done:
ComponentWhat
1. Clinical examinationHistory + full breast exam
2. ImagingMammogram (<35 yrs: USG; >35 yrs: Mammogram ± USG)
3. Tissue samplingFNAC (cytology) or Core needle biopsy (histology)
If all 3 are benign = safe to observe. If ANY is suspicious = proceed to excision/surgery.

5. INVESTIGATIONS

Imaging

Mammography
  • Investigation of choice for women >35-40 years
  • Two views: craniocaudal (CC) and mediolateral oblique (MLO)
  • Malignant features: spiculated mass, pleomorphic calcifications, skin thickening, nipple retraction
  • BIRADS classification: BIRADS 1 = normal; BIRADS 5 = highly suggestive malignancy
  • Screening mammogram: every 2 years for women 50-74 yrs (national programs)
Ultrasound (USG)
  • Preferred for women <35 years (dense breast tissue makes mammography less useful)
  • Distinguishes solid vs cystic lesions
  • Guides FNAC/core biopsy
  • Benign features: smooth margins, posterior acoustic enhancement (cyst)
  • Malignant features: irregular hypoechoic mass, spiculated margins, posterior shadowing
MRI Breast
  • Not routine; used for:
    • BRCA mutation carriers (high-risk screening)
    • Assessing extent of lobular carcinoma
    • Occult primary breast cancer with axillary nodes
    • Pre-operative planning for BCS (breast conserving surgery)
    • Implants assessment

Tissue Diagnosis

FNAC (Fine Needle Aspiration Cytology)
  • 22-25G needle, syringe, no anaesthesia
  • Gives cytological diagnosis only
  • Reports as: C1 (inadequate) / C2 (benign) / C3 (atypia) / C4 (suspicious) / C5 (malignant)
  • Advantage: quick, cheap, outpatient
  • Limitation: cannot distinguish invasive from in-situ cancer; cannot give hormone receptor status
Core Needle Biopsy (Tru-cut)
  • 14-16G needle; gives a core of tissue = histological diagnosis
  • Can determine: invasive vs in-situ; grade; ER/PR/HER2 status
  • Preferred over FNAC when preoperative planning is needed
Excision Biopsy
  • When FNAC/core is inconclusive (Bethesda III equivalent / C3)
  • Provides definitive diagnosis

Blood Tests

  • CBC - anaemia in advanced disease
  • LFT, ALP - liver / bone metastases
  • Serum calcium - hypercalcaemia in bone metastases
  • Tumour markers: CA 15-3, CEA - used for monitoring treatment response, not diagnosis
  • Hormone receptor status (ER, PR, HER2) on biopsy - determines treatment

Staging Investigations (if cancer confirmed)

  • Chest X-ray - lung metastases
  • CT chest / abdomen / pelvis - staging
  • Bone scan - bone metastases (indicated if bone pain or raised ALP)
  • PET-CT - accurate staging in high-risk disease

6. STAGING OF BREAST CANCER

TNM Classification

TDescription
T1≤2 cm; no fixation; no nipple retraction
T22-5 cm; skin may be tethered; no pectoral fixation
T3>5 cm; skin fixed or ulcerated; pectoral fixation
T4Chest wall fixation; peau d'orange over large area; inflammatory carcinoma
NDescription
N0No palpable ipsilateral nodes
N1Mobile ipsilateral axillary nodes
N2Fixed axillary nodes
N3Supraclavicular / infraclavicular nodes; arm oedema
MDescription
M0No distant metastasis
M1Distant metastasis present

Clinical Stages (S Das)

  • Stage I: Growth limited to breast; ± small skin adherence
  • Stage II: + Mobile axillary nodes; ± slight pectoral tethering
  • Stage III: Fixed to pectoral muscle; skin involvement > tumour size
  • Stage IV: Fixed to chest wall; fixed axillary nodes; supraclavicular nodes; distant metastases

7. TYPES OF BREAST CARCINOMA

TypeFeatures
Scirrhous carcinomaMost common; very hard, fibrotic; slow growing; infiltrative
Atrophic scirrhousLeast malignant; very slow growing; may mimic benign
Encephaloid (Medullary)Soft brain-like; rapidly growing; less fibrosis; better prognosis
ComedocarcinomaIntraductal; DCIS type; "toothpaste-like" plugs from ducts
Colloid (Mucinous)Gelatinous; better prognosis; older women
Mastitis carcinomatosa (Inflammatory Ca)Most malignant; entire breast red, hot, oedematous; no palpable lump; poor prognosis
Paget's disease of nippleEczema-like change of nipple; underlying DCIS or invasive Ca; always biopsy
Lobular carcinomaDiffuse, bilateral; harder to detect on mammogram
Metastatic spread:
  • Lymphatic: Axillary nodes (most common) → supraclavicular → internal mammary nodes
  • Blood: Bones (most common - especially spine, pelvis, femur), lung, liver, brain, ovary (transcoelomic)

8. MANAGEMENT

Benign Conditions

ConditionManagement
FibroadenomaSmall (<3 cm): observe; large / growing / symptomatic: excision
Breast cystAspiration (diagnostic + therapeutic); if bloody fluid / residual lump → biopsy
FibroadenosisReassurance; evening primrose oil; danazol for severe mastalgia
Mastitis / AbscessAntibiotics (flucloxacillin); if abscess = incision and drainage (I&D) or needle aspiration
Duct papillomaMicrodochectomy (excision of affected duct); considered premalignant
Cystosarcoma phylloidesWide local excision or simple mastectomy (tends to recur); rarely malignant
GynaecomastiaTreat cause; if persists / painful: subcutaneous mastectomy

Malignant Conditions - Breast Cancer Surgery

Breast Surgery Options

ProcedureIndication
Wide Local Excision (WLE) / LumpectomyEarly cancer; followed by radiotherapy = Breast Conserving Surgery (BCS)
QuadrantectomyRemoval of involved quadrant
Simple (Total) MastectomyCarcinoma in-situ; prophylactic (BRCA1/2); when BCS not possible
Modified Radical Mastectomy (MRM)Most common surgery for breast cancer today; removes breast + axillary nodes; preserves pectoralis major
Radical Mastectomy (Halsted)Historical; removes breast + pectoralis major + minor + axillary nodes; rarely done now
Extended Radical MastectomyAlso removes internal mammary nodes; obsolete

Axillary Management

ProcedureIndication
Sentinel Lymph Node Biopsy (SLNB)Clinically node-negative axilla; if SLNB negative = no further axillary surgery
Axillary Lymph Node Dissection (ALND)SLNB positive; clinically / radiologically positive nodes

Adjuvant Therapy

TreatmentIndication
RadiotherapyPost-BCS (mandatory); post-mastectomy in high-risk; chest wall
ChemotherapyTriple-negative, HER2+, high-grade, node-positive disease
Hormonal therapy (Tamoxifen / Aromatase inhibitors)ER/PR positive (5-10 years)
HER2 targeted (Trastuzumab/Herceptin)HER2-positive tumours

9. HIGH-YIELD VIVA QUESTIONS & ANSWERS

Q: What is the most common site of carcinoma in the breast? A: Upper outer quadrant (UOQ) - approximately 50% of all breast carcinomas. It has the greatest volume of breast tissue and the axillary tail.
Q: What is "peau d'orange" and what causes it? A: Peau d'orange (French: "skin of an orange") is oedema of the breast skin with deepening of the sweat gland and hair follicle openings, giving an orange-peel appearance. It is caused by obstruction of the subcuticular lymphatics by cancer cells, leading to skin oedema, while the tethered skin over follicles cannot expand - creating the pitted appearance.
Q: What is Cooper's ligament and what happens when it is invaded? A: Cooper's ligaments (suspensory ligaments of the breast) are fibrous septae passing from the glandular breast tissue to the overlying skin. When invaded by carcinoma, they become shorter and inelastic, pulling the skin inwards, causing skin dimpling, puckering or retraction.
Q: What is a "breast mouse"? A: A fibroadenoma - it is highly mobile within the breast substance and freely movable under the examining fingers, hence the term. It is NOT fixed to the skin or deeper structures.
Q: What is Paget's disease of the nipple? A: A form of breast cancer presenting as eczema-like changes (scaling, weeping, crusting) of the nipple and areola. It represents extension of an underlying ductal carcinoma in-situ (DCIS) or invasive carcinoma through the lactiferous ducts to the nipple epidermis. Always biopsy nipple eczema in a woman over 40. Treatment: total mastectomy or BCS + nipple excision + radiotherapy.
Q: "Breast cancer is painless" - always true? A: Painless at onset - all neoplasms of the breast (benign or malignant) are painless to start. However, late-stage carcinoma can cause pain from bone metastases (back, hip, shoulder pain). Inflammatory carcinoma is a painful exception. Pain should never be used to exclude carcinoma.
Q: What is the most common type of breast cancer? A: Invasive ductal carcinoma (IDC) / scirrhous carcinoma - accounts for ~75-80% of all breast cancers. Presents as a hard, stony, irregular mass with fibrous stroma.
Q: What is the difference between tethering and fixation to skin?
  • Tethering: Malignancy has spread to Cooper's ligaments; lump can still move independently through a small range, but skin dimples at the extremes of movement. (T2 feature)
  • Fixed: Direct infiltration of skin by tumour; lump cannot be moved independently at all; overlying skin cannot be pinched up. (T4 feature)
Q: What is triple assessment? A: The gold standard approach for evaluating any breast lump:
  1. Clinical examination
  2. Imaging (mammogram ± ultrasound)
  3. Tissue sampling (FNAC or core biopsy) All three results must be concordant. If any one is suspicious → proceed to surgery.
Q: How do you test for fixity to pectoralis major? A: Ask the patient to press her hand on her hip (muscle relaxed) - assess lump mobility. Then ask her to press as hard as possible (muscle taut) - retest mobility in the line of the muscle fibres. Restricted mobility with the muscle contracted indicates fixity to pectoralis major or pectoral fascia.
Q: What is Modified Radical Mastectomy (MRM)? A: Removal of the entire breast + all axillary lymph nodes, while preserving both pectoralis major and minor. This is the standard surgical procedure for breast cancer today. It replaced Halsted's radical mastectomy (which removed both pectoral muscles) as outcomes were equivalent with less morbidity.
Q: Most common site of blood-borne metastasis from breast cancer? A: Bones (spine, pelvis, femur) - most common. Others: lungs, liver, brain, ovary (Krukenberg - transcoelomic).
Q: Risk factors for breast cancer? A: MNEMONIC - "FEMALE BRAS"
  • Family history (first-degree relative, BRCA1/2)
  • Early menarche (<12 yrs)
  • Menopause late (>55 yrs)
  • Age (>40 yrs)
  • Late first pregnancy / nulliparity
  • Exposure to radiation
  • Body weight (obesity - increases oestrogen)
  • Risk from HRT / OCP
  • Alcohol, diet rich in saturated fat
  • Socioeconomic (more in Western world)
Q: What is inflammatory carcinoma? A: The most malignant type of breast cancer (mastitis carcinomatosa). The entire breast becomes red, hot, swollen, oedematous - resembling acute mastitis. There may be no discrete palpable mass. Due to massive lymphatic infiltration causing dermal lymphatic obstruction. Very poor prognosis. Treatment: neoadjuvant chemotherapy first, then surgery + radiotherapy. Do NOT mistake it for mastitis and delay diagnosis.

Sources: S Das - A Manual on Clinical Surgery, 13th ed. | Bailey & Love's Short Practice of Surgery, 28th ed. | Schwartz's Principles of Surgery, 11th ed. | Harrison's Principles of Internal Medicine, 22E

Create a PDF summary of breast examination techniques with diagrams

Reading File
Running Command

ls -la /home/daytona/workspace/ && mkdir -p /home/daytona/workspace/breast-exam-pdf

Writing File

~/breast-exam-pdf/create_pdf.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
                                 TableStyle, HRFlowable, PageBreak, KeepTogether)
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.graphics.shapes import Drawing, Rect, Circle, Line, String, Ellipse, Polygon
from reportlab.graphics import renderPDF
from reportlab.platypus.flowables import Flowable
import io

# ─── Color palette ───────────────────────────────────────────────────────────
TEAL        = colors.HexColor("#006B6B")
TEAL_LIGHT  = colors.HexColor("#E0F4F4")
TEAL_MED    = colors.HexColor("#B2DEDE")
ROSE        = colors.HexColor("#C0392B")
ROSE_LIGHT  = colors.HexColor("#FDECEA")
GOLD        = colors.HexColor("#D4AC0D")
GOLD_LIGHT  = colors.HexColor("#FEF9E7")
DARK        = colors.HexColor("#1C2833")
MID         = colors.HexColor("#4A4A4A")
LIGHT_GRAY  = colors.HexColor("#F4F6F9")
BORDER_GRAY = colors.HexColor("#D5D8DC")
WHITE       = colors.white
RED_FLAG    = colors.HexColor("#E74C3C")
GREEN_OK    = colors.HexColor("#1E8449")

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

title_style = ParagraphStyle('Title', fontName='Helvetica-Bold', fontSize=22,
                              textColor=WHITE, alignment=TA_CENTER, spaceAfter=4)
subtitle_style = ParagraphStyle('Subtitle', fontName='Helvetica', fontSize=11,
                                 textColor=TEAL_LIGHT, alignment=TA_CENTER, spaceAfter=2)
h1 = ParagraphStyle('H1', fontName='Helvetica-Bold', fontSize=13,
                     textColor=WHITE, alignment=TA_LEFT, spaceAfter=4, leftIndent=6)
h2 = ParagraphStyle('H2', fontName='Helvetica-Bold', fontSize=11,
                     textColor=TEAL, alignment=TA_LEFT, spaceBefore=8, spaceAfter=4)
h3 = ParagraphStyle('H3', fontName='Helvetica-Bold', fontSize=10,
                     textColor=DARK, alignment=TA_LEFT, spaceBefore=4, spaceAfter=3)
body = ParagraphStyle('Body', fontName='Helvetica', fontSize=9,
                       textColor=DARK, alignment=TA_JUSTIFY, spaceAfter=3, leading=13)
bullet = ParagraphStyle('Bullet', fontName='Helvetica', fontSize=9,
                         textColor=DARK, leftIndent=14, spaceAfter=2, leading=12,
                         bulletIndent=4)
red_text = ParagraphStyle('Red', fontName='Helvetica-Bold', fontSize=9,
                           textColor=RED_FLAG, spaceAfter=2)
green_text = ParagraphStyle('Green', fontName='Helvetica-Bold', fontSize=9,
                              textColor=GREEN_OK, spaceAfter=2)
small = ParagraphStyle('Small', fontName='Helvetica', fontSize=8,
                        textColor=MID, spaceAfter=2, leading=11)
caption = ParagraphStyle('Caption', fontName='Helvetica-Oblique', fontSize=8,
                          textColor=MID, alignment=TA_CENTER, spaceAfter=6)
tip_style = ParagraphStyle('Tip', fontName='Helvetica', fontSize=9,
                            textColor=DARK, leftIndent=10, spaceAfter=2, leading=12)

# ─── Header/Footer ────────────────────────────────────────────────────────────
def add_header_footer(canvas, doc):
    canvas.saveState()
    W, H = A4
    # Top bar
    canvas.setFillColor(TEAL)
    canvas.rect(0, H - 22*mm, W, 22*mm, fill=True, stroke=False)
    canvas.setFillColor(WHITE)
    canvas.setFont('Helvetica-Bold', 10)
    canvas.drawString(15*mm, H - 13*mm, "BREAST EXAMINATION - Surgical Viva Guide")
    canvas.setFont('Helvetica', 8)
    canvas.drawRightString(W - 15*mm, H - 13*mm, f"Page {doc.page}")
    # Bottom bar
    canvas.setFillColor(TEAL)
    canvas.rect(0, 0, W, 10*mm, fill=True, stroke=False)
    canvas.setFillColor(WHITE)
    canvas.setFont('Helvetica', 7)
    canvas.drawCentredString(W/2, 3.5*mm, "Based on S Das - A Manual on Clinical Surgery | Bailey & Love | Schwartz's Principles of Surgery")
    canvas.restoreState()

# ─── Diagram helpers ─────────────────────────────────────────────────────────

class BreastQuadrantDiagram(Flowable):
    """Breast quadrant anatomy diagram"""
    def __init__(self, width=180, height=180):
        Flowable.__init__(self)
        self.width = width
        self.height = height

    def draw(self):
        c = self.canv
        cx, cy = self.width/2, self.height/2
        r = 70

        # Background circle (breast outline)
        c.setFillColor(colors.HexColor("#FFE4E1"))
        c.setStrokeColor(colors.HexColor("#C0392B"))
        c.setLineWidth(1.5)
        c.circle(cx, cy, r, fill=True, stroke=True)

        # Quadrant dividers
        c.setStrokeColor(colors.HexColor("#888888"))
        c.setLineWidth(0.8)
        c.setDash(4, 2)
        c.line(cx, cy - r, cx, cy + r)     # vertical
        c.line(cx - r, cy, cx + r, cy)     # horizontal
        c.setDash()

        # Nipple/areola
        c.setFillColor(colors.HexColor("#C9706A"))
        c.setStrokeColor(colors.HexColor("#C0392B"))
        c.setLineWidth(0.8)
        c.circle(cx, cy, 10, fill=True, stroke=True)
        c.setFillColor(colors.HexColor("#D4907A"))
        c.circle(cx, cy, 5, fill=True, stroke=False)

        # Quadrant labels
        c.setFont('Helvetica-Bold', 8)
        c.setFillColor(DARK)
        c.drawCentredString(cx - 28, cy + 30, "UOQ")
        c.setFont('Helvetica', 7)
        c.setFillColor(ROSE)
        c.drawCentredString(cx - 28, cy + 20, "50%")
        c.setFont('Helvetica', 6.5)
        c.setFillColor(MID)
        c.drawCentredString(cx - 28, cy + 11, "most common")

        c.setFont('Helvetica-Bold', 8)
        c.setFillColor(DARK)
        c.drawCentredString(cx + 28, cy + 30, "UIQ")
        c.setFont('Helvetica', 7)
        c.setFillColor(MID)
        c.drawCentredString(cx + 28, cy + 20, "15%")

        c.setFont('Helvetica-Bold', 8)
        c.setFillColor(DARK)
        c.drawCentredString(cx - 28, cy - 22, "LOQ")
        c.setFont('Helvetica', 7)
        c.setFillColor(MID)
        c.drawCentredString(cx - 28, cy - 31, "10%")

        c.setFont('Helvetica-Bold', 8)
        c.setFillColor(DARK)
        c.drawCentredString(cx + 28, cy - 22, "LIQ")
        c.setFont('Helvetica', 7)
        c.setFillColor(MID)
        c.drawCentredString(cx + 28, cy - 31, "5%")

        # Axillary tail arrow
        c.setStrokeColor(TEAL)
        c.setFillColor(TEAL)
        c.setLineWidth(1.2)
        # Draw arrow pointing upper-left-ish
        ax1, ay1 = cx - 50, cy + 50
        ax2, ay2 = cx - 62, cy + 62
        c.line(ax1, ay1, ax2, ay2)
        c.setFont('Helvetica-Bold', 7)
        c.setFillColor(TEAL)
        c.drawString(cx - 78, cy + 62, "Axillary")
        c.drawString(cx - 78, cy + 54, "tail (20%)")

        # Central (retroareolar) label
        c.setFont('Helvetica', 6.5)
        c.setFillColor(WHITE)
        c.drawCentredString(cx, cy - 15, "Central")

        # Labels outer
        c.setFont('Helvetica-Bold', 7.5)
        c.setFillColor(DARK)
        c.drawCentredString(cx, cy + r + 10, "UPPER")
        c.drawCentredString(cx, cy - r - 12, "LOWER")
        c.drawString(cx - r - 15, cy - 3, "LATERAL")
        c.drawString(cx + r + 3, cy - 3, "MEDIAL")


class PectoralisFixityDiagram(Flowable):
    """Diagram showing pectoralis fixity test"""
    def __init__(self, width=260, height=140):
        Flowable.__init__(self)
        self.width = width
        self.height = height

    def draw(self):
        c = self.canv
        # Panel A - relaxed
        self._draw_panel(c, 10, 10, 110, 120, relaxed=True, label="A) Muscle RELAXED")
        # Panel B - contracted
        self._draw_panel(c, 140, 10, 110, 120, relaxed=False, label="B) Muscle CONTRACTED")

    def _draw_panel(self, c, x, y, w, h, relaxed, label):
        # Background
        c.setFillColor(LIGHT_GRAY)
        c.setStrokeColor(BORDER_GRAY)
        c.setLineWidth(0.5)
        c.roundRect(x, y, w, h, 6, fill=True, stroke=True)

        cx, cy = x + w/2, y + h/2

        # Chest wall
        c.setFillColor(colors.HexColor("#D5E8D4"))
        c.setStrokeColor(colors.HexColor("#82B366"))
        c.rect(x+8, y+20, w-16, 18, fill=True, stroke=True)
        c.setFont('Helvetica', 7)
        c.setFillColor(colors.HexColor("#2D6A4F"))
        c.drawCentredString(cx, y+27, "Pectoralis Major")

        # Breast outline
        c.setFillColor(colors.HexColor("#FFE4E1"))
        c.setStrokeColor(ROSE)
        c.setLineWidth(1)
        c.ellipse(cx-28, y+38, cx+28, y+85, fill=True, stroke=True)

        # Tumour
        c.setFillColor(colors.HexColor("#8B0000"))
        c.circle(cx, y+62, 10, fill=True, stroke=False)

        # Arrow showing mobility
        if relaxed:
            c.setStrokeColor(GREEN_OK)
            c.setLineWidth(1.5)
            c.line(cx-22, y+62, cx-36, y+62)
            c.line(cx+22, y+62, cx+36, y+62)
            # arrowheads
            c.setFillColor(GREEN_OK)
            c.polygon([cx-36, y+62, cx-30, y+65, cx-30, y+59], fill=True)
            c.polygon([cx+36, y+62, cx+30, y+65, cx+30, y+59], fill=True)
            c.setFont('Helvetica-Bold', 7.5)
            c.setFillColor(GREEN_OK)
            c.drawCentredString(cx, y+56, "Freely mobile")
        else:
            c.setStrokeColor(RED_FLAG)
            c.setLineWidth(1.5)
            # X marks
            c.line(cx-20, y+52, cx-8, y+45)
            c.line(cx-8, y+52, cx-20, y+45)
            c.line(cx+8, y+52, cx+20, y+45)
            c.line(cx+20, y+52, cx+8, y+45)
            c.setFont('Helvetica-Bold', 7.5)
            c.setFillColor(RED_FLAG)
            c.drawCentredString(cx, y+38, "Restricted = FIXED")

        # Label
        c.setFont('Helvetica-Bold', 8)
        c.setFillColor(DARK)
        c.drawCentredString(cx, y + h - 10, label)


class SkinFixityDiagram(Flowable):
    """Tethering vs fixation"""
    def __init__(self, width=260, height=130):
        Flowable.__init__(self)
        self.width = width
        self.height = height

    def draw(self):
        c = self.canv
        self._panel(c, 5, 5, 115, 120, tethered=True)
        self._panel(c, 140, 5, 115, 120, tethered=False)

    def _panel(self, c, x, y, w, h, tethered):
        c.setFillColor(LIGHT_GRAY)
        c.setStrokeColor(BORDER_GRAY)
        c.setLineWidth(0.5)
        c.roundRect(x, y, w, h, 6, fill=True, stroke=True)

        cx = x + w/2

        # Skin layer
        skin_y = y + h - 22
        c.setFillColor(colors.HexColor("#F5CBA7"))
        c.setStrokeColor(colors.HexColor("#E59866"))
        c.setLineWidth(0.8)
        c.rect(x+8, skin_y, w-16, 12, fill=True, stroke=True)
        c.setFont('Helvetica', 6.5)
        c.setFillColor(DARK)
        c.drawCentredString(cx, skin_y+4, "Skin")

        # Breast tissue
        c.setFillColor(colors.HexColor("#FFE4E1"))
        c.setStrokeColor(ROSE)
        c.setLineWidth(0.8)
        c.rect(x+8, y+30, w-16, skin_y - y - 32, fill=True, stroke=True)

        # Tumour
        tum_y = y + 55
        c.setFillColor(colors.HexColor("#8B0000"))
        c.circle(cx, tum_y, 11, fill=True, stroke=False)

        if tethered:
            # Cooper's ligaments - normal to tethered
            c.setStrokeColor(colors.HexColor("#884EA0"))
            c.setLineWidth(0.8)
            # Ligament lines pulling skin
            for ox in [-12, -5, 0, 5, 12]:
                c.line(cx + ox*0.5, tum_y - 11, cx + ox, skin_y)
            # Skin dimple
            c.setFillColor(colors.HexColor("#F5CBA7"))
            c.setStrokeColor(colors.HexColor("#E59866"))
            # draw a small inward dimple in skin
            c.bezier(cx-10, skin_y, cx-3, skin_y-5, cx+3, skin_y-5, cx+10, skin_y)

            c.setFont('Helvetica-Bold', 8)
            c.setFillColor(colors.HexColor("#884EA0"))
            c.drawCentredString(cx, y+18, "TETHERING")
            c.setFont('Helvetica', 6.5)
            c.setFillColor(DARK)
            c.drawCentredString(cx, y+10, "Cooper's lig. infiltrated")
        else:
            # Fixed - direct connection
            c.setFillColor(colors.HexColor("#8B0000"))
            c.rect(cx-4, tum_y+10, 8, skin_y - tum_y - 10, fill=True, stroke=False)

            c.setFont('Helvetica-Bold', 8)
            c.setFillColor(RED_FLAG)
            c.drawCentredString(cx, y+18, "FIXATION")
            c.setFont('Helvetica', 6.5)
            c.setFillColor(DARK)
            c.drawCentredString(cx, y+10, "Direct skin infiltration")


class InspectionPositionsDiagram(Flowable):
    """Four inspection positions as stick figures"""
    def __init__(self, width=460, height=110):
        Flowable.__init__(self)
        self.width = width
        self.height = height

    def _stick_figure(self, c, x, y, arms='down', label=''):
        # Head
        c.setFillColor(colors.HexColor("#FAD7A0"))
        c.setStrokeColor(DARK)
        c.setLineWidth(0.8)
        c.circle(x, y+85, 10, fill=True, stroke=True)
        # Body
        c.setStrokeColor(DARK)
        c.setLineWidth(1.2)
        c.line(x, y+75, x, y+40)  # torso
        # Legs
        c.line(x, y+40, x-12, y+10)
        c.line(x, y+40, x+12, y+10)

        if arms == 'down':
            c.line(x, y+68, x-18, y+50)
            c.line(x, y+68, x+18, y+50)
        elif arms == 'up':
            c.line(x, y+68, x-15, y+88)
            c.line(x, y+68, x+15, y+88)
        elif arms == 'hip':
            c.line(x, y+68, x-20, y+60)
            c.line(x-20, y+60, x-14, y+52)
            c.line(x, y+68, x+20, y+60)
            c.line(x+20, y+60, x+14, y+52)
        elif arms == 'forward':
            c.line(x, y+68, x-16, y+55)
            c.line(x, y+68, x+16, y+55)
            # tilt body
        # Label
        c.setFont('Helvetica-Bold', 7.5)
        c.setFillColor(TEAL)
        c.drawCentredString(x, y, label)

    def draw(self):
        c = self.canv
        positions = [
            (55,  5, 'down', 'Pos 1: Arms\nat rest'),
            (170, 5, 'up',   'Pos 2: Arms\nraised'),
            (285, 5, 'hip',  'Pos 3: Hands\non hips'),
            (400, 5, 'forward', 'Pos 4: Lean\nforward'),
        ]
        nums = ['1', '2', '3', '4']
        for (x, y, arms, label), num in zip(positions, nums):
            # Box
            c.setFillColor(TEAL_LIGHT)
            c.setStrokeColor(TEAL_MED)
            c.setLineWidth(0.5)
            c.roundRect(x-45, y, 88, 105, 6, fill=True, stroke=True)
            # Number badge
            c.setFillColor(TEAL)
            c.circle(x-30, y+96, 9, fill=True, stroke=False)
            c.setFont('Helvetica-Bold', 9)
            c.setFillColor(WHITE)
            c.drawCentredString(x-30, y+93, num)
            self._stick_figure(c, x, y+3, arms=arms, label='')
            # label below
            c.setFont('Helvetica-Bold', 7.5)
            c.setFillColor(TEAL)
            for i, line in enumerate(label.split('\n')):
                c.drawCentredString(x, y + 3 + i*9, line)


# ─── Content builder ─────────────────────────────────────────────────────────

def section_header(text, color=TEAL):
    d = Drawing(460, 22)
    d.add(Rect(0, 0, 460, 22, fillColor=color, strokeColor=None))
    d.add(String(10, 6, text, fontName='Helvetica-Bold', fontSize=12, fillColor=WHITE))
    return d

def tip_box(text, bg=TEAL_LIGHT, border=TEAL):
    data = [[Paragraph(text, tip_style)]]
    t = Table(data, colWidths=[440])
    t.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,-1), bg),
        ('BOX', (0,0), (-1,-1), 1, border),
        ('LEFTPADDING', (0,0), (-1,-1), 8),
        ('RIGHTPADDING', (0,0), (-1,-1), 8),
        ('TOPPADDING', (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
        ('ROUNDEDCORNERS', (0,0), (-1,-1), [4,4,4,4]),
    ]))
    return t

def warning_box(text):
    return tip_box(text, bg=ROSE_LIGHT, border=ROSE)

def gold_box(text):
    return tip_box(text, bg=GOLD_LIGHT, border=GOLD)

def make_table(headers, rows, col_widths):
    data = [headers] + rows
    t = Table(data, colWidths=col_widths)
    style = TableStyle([
        ('BACKGROUND', (0,0), (-1,0), TEAL),
        ('TEXTCOLOR', (0,0), (-1,0), WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,0), 8.5),
        ('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
        ('FONTSIZE', (0,1), (-1,-1), 8),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LIGHT_GRAY]),
        ('BOX', (0,0), (-1,-1), 0.8, BORDER_GRAY),
        ('INNERGRID', (0,0), (-1,-1), 0.4, BORDER_GRAY),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 3),
        ('BOTTOMPADDING', (0,0), (-1,-1), 3),
        ('LEFTPADDING', (0,0), (-1,-1), 5),
    ])
    t.setStyle(style)
    return t

def bp(text):
    return Paragraph(f"<bullet>&bull;</bullet> {text}", bullet)

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

# ─── Cover page ───────────────────────────────────────────────────────────────

def cover_page():
    elems = []
    elems.append(Spacer(1, 2*cm))

    # Main title block
    d = Drawing(460, 120)
    d.add(Rect(0, 0, 460, 120, fillColor=TEAL, strokeColor=None, rx=10, ry=10))
    d.add(Rect(0, 0, 460, 4, fillColor=GOLD, strokeColor=None))
    d.add(Rect(0, 116, 460, 4, fillColor=GOLD, strokeColor=None))
    d.add(String(230, 78, "BREAST EXAMINATION", textAnchor='middle',
                 fontName='Helvetica-Bold', fontSize=24, fillColor=WHITE))
    d.add(String(230, 52, "Surgical Viva Guide", textAnchor='middle',
                 fontName='Helvetica', fontSize=15, fillColor=TEAL_LIGHT))
    d.add(String(230, 28, "History  •  Inspection  •  Palpation  •  Special Tests  •  Differentials",
                 textAnchor='middle', fontName='Helvetica', fontSize=9, fillColor=TEAL_MED))
    elems.append(d)
    elems.append(sp(12))

    # Subtitle box
    sub = Table([[Paragraph("Complete clinical approach to the breast for MBBS / MS Surgery viva examinations", subtitle_style)]],
                colWidths=[440])
    sub.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),TEAL_LIGHT),
                              ('BOX',(0,0),(-1,-1),1,TEAL),
                              ('TOPPADDING',(0,0),(-1,-1),8),
                              ('BOTTOMPADDING',(0,0),(-1,-1),8)]))
    elems.append(sub)
    elems.append(sp(20))

    # Contents box
    contents = [
        ["01", "History Taking", "Patient details, lump, pain, discharge, risk factors"],
        ["02", "Inspection", "4 positions, skin signs, nipple changes"],
        ["03", "Palpation", "14-point lump assessment, fixity tests"],
        ["04", "Special Tests", "Pectoralis, serratus, chest wall, transillumination"],
        ["05", "Axilla Examination", "Node groups, technique"],
        ["06", "Differential Diagnosis", "Fibroadenoma vs carcinoma vs cyst vs fibroadenosis"],
        ["07", "Malignant Features", "Red flag signs on examination"],
        ["08", "Investigations", "Triple assessment, mammography, FNAC, core biopsy"],
        ["09", "Staging & Classification", "TNM, clinical stages"],
        ["10", "High-Yield Viva Q&A", "Classic viva traps and answers"],
    ]
    tbl = Table(
        [["#", "Section", "Contents"]] + contents,
        colWidths=[28, 130, 282]
    )
    tbl.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), DARK),
        ('TEXTCOLOR', (0,0), (-1,0), WHITE),
        ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE', (0,0), (-1,0), 9),
        ('BACKGROUND', (0,1), (0,-1), TEAL),
        ('TEXTCOLOR', (0,1), (0,-1), WHITE),
        ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
        ('FONTSIZE', (0,1), (0,-1), 9),
        ('FONTNAME', (1,1), (1,-1), 'Helvetica-Bold'),
        ('FONTSIZE', (1,1), (1,-1), 8.5),
        ('FONTNAME', (2,1), (2,-1), 'Helvetica'),
        ('FONTSIZE', (2,1), (2,-1), 8),
        ('ROWBACKGROUNDS', (1,1), (-1,-1), [WHITE, LIGHT_GRAY]),
        ('BOX', (0,0), (-1,-1), 0.8, BORDER_GRAY),
        ('INNERGRID', (0,0), (-1,-1), 0.3, BORDER_GRAY),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 6),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
    ]))
    elems.append(tbl)
    elems.append(sp(16))

    # Source
    src = Paragraph("<i>Sources: S Das - A Manual on Clinical Surgery (13th ed.) | Bailey &amp; Love's Short Practice of Surgery (28th ed.) | Schwartz's Principles of Surgery (11th ed.)</i>", small)
    elems.append(src)
    elems.append(PageBreak())
    return elems

# ─── Page 2: History + Inspection ────────────────────────────────────────────
def page_history_inspection():
    elems = []

    # Section 1
    elems.append(section_header("01  HISTORY TAKING"))
    elems.append(sp(6))

    elems.append(Paragraph("Key Demographic Factors", h2))
    age_data = [
        [Paragraph("<b>Age Group</b>", small), Paragraph("<b>Most Likely Diagnosis</b>", small)],
        ["< 35 years", "Fibroadenoma (most likely)"],
        ["20 - 40 years", "Fibroadenosis (mammary dysplasia)"],
        ["> 40 years", "Carcinoma must always be excluded"],
        ["Lactating woman (any age)", "Mastitis / breast abscess"],
        ["Male patient", "Gynaecomastia; rarely carcinoma"],
    ]
    elems.append(make_table(age_data[0:1], age_data[1:], [120, 320]))
    elems.append(sp(6))

    elems.append(Paragraph("Chief Complaint - Lump", h2))
    elems.append(bp("<b>Duration & onset:</b> Long history + slow growth = benign; Short history + fast growth = malignant"))
    elems.append(bp("<b>Sudden enlargement</b> into a lump = haemorrhage into a cyst or nodule"))
    elems.append(bp("Average time from patient discovering lump to surgeon = <b>~6 weeks</b> in carcinoma"))
    elems.append(sp(4))
    elems.append(warning_box("⚠ VIVA TRAP: Carcinoma of the breast is PAINLESS at onset. A painless lump accidentally discovered during washing must NEVER be ignored - it is carcinoma until proven otherwise."))
    elems.append(sp(6))

    elems.append(Paragraph("Pain (Mastalgia)", h2))
    pain_rows = [
        ["Throbbing, severe", "Acute mastitis / breast abscess (pus formation)"],
        ["Cyclical, premenstrual", "Fibroadenosis - most common benign cause"],
        ["Non-cyclical, localised", "Periductal mastitis, fat necrosis, musculoskeletal"],
        ["Back / hip / shoulder", "Bony metastases from carcinoma (late feature)"],
        ["Painless lump", "MUST rule out carcinoma"],
    ]
    elems.append(make_table(
        [Paragraph("<b>Pain Character</b>", small), Paragraph("<b>Likely Diagnosis</b>", small)],
        pain_rows, [160, 280]))
    elems.append(sp(6))

    elems.append(Paragraph("Nipple Discharge", h2))
    disc_rows = [
        ["Bright red / blood", "Duct papilloma (most common), duct carcinoma"],
        ["Serous / clear", "Early duct papilloma, carcinoma"],
        ["Green / brown", "Fibroadenosis, duct ectasia"],
        ["White (milky)", "Galactorrhoea - prolactinoma, drugs (phenothiazines, metoclopramide)"],
        ["Purulent", "Abscess, infected duct ectasia"],
    ]
    elems.append(make_table(
        [Paragraph("<b>Colour</b>", small), Paragraph("<b>Diagnosis</b>", small)],
        disc_rows, [130, 310]))
    elems.append(sp(6))

    elems.append(Paragraph("Risk Factors for Breast Carcinoma", h2))
    risk_rows = [
        ["Family history", "First-degree relative (mother/sister); BRCA1 / BRCA2 mutation"],
        ["Age", "> 40 years; incidence increases with age"],
        ["Reproductive", "Early menarche (<12 yrs); late menopause (>55 yrs); nulliparity; first child >30 yrs"],
        ["Hormonal", "HRT (long-term); OCP (slight risk); obesity (↑ oestrogen post-menopause)"],
        ["Previous disease", "Contralateral breast Ca; atypical ductal hyperplasia; LCIS"],
        ["Radiation", "Chest wall irradiation in childhood (e.g. for lymphoma)"],
        ["Lifestyle", "Alcohol; diet rich in saturated fat; sedentary"],
        ["Male factors", "Klinefelter syndrome; oestrogen therapy; liver disease"],
    ]
    elems.append(make_table(
        [Paragraph("<b>Risk Factor</b>", small), Paragraph("<b>Detail</b>", small)],
        risk_rows, [120, 320]))
    elems.append(sp(6))

    elems.append(gold_box("✔ MNEMONIC - Risk factors: FEMALE BRAS  →  Family history | Early menarche | Menopause late | Age >40 | Late 1st pregnancy | Exposure to radiation | Body weight/obesity | Race/HRT | Alcohol | Sedentary"))
    elems.append(sp(8))

    # Section 2
    elems.append(section_header("02  INSPECTION"))
    elems.append(sp(6))

    elems.append(Paragraph("Setup & Patient Position", h2))
    elems.append(bp("Patient <b>seated</b>, fully exposed to nipple level; adequate privacy + chaperone"))
    elems.append(bp("Adequate lighting; examine from in front and then from the side"))
    elems.append(bp("Examine the <b>normal breast first</b> to establish baseline"))
    elems.append(sp(6))

    elems.append(Paragraph("Four Inspection Positions", h2))
    elems.append(InspectionPositionsDiagram(width=460, height=110))
    elems.append(sp(4))

    pos_rows = [
        ["1. Arms at rest (sides)", "Symmetry, contour, skin changes, nipple position"],
        ["2. Arms raised above head", "Lower surfaces visible; reveals hidden lumps, puckering, axillae"],
        ["3. Hands pressed on hips", "Tenses pectoralis; accentuates tethering / dimpling"],
        ["4. Leaning forward", "Pendulous breasts fall; reveals undersurface and asymmetry"],
    ]
    elems.append(make_table(
        [Paragraph("<b>Position</b>", small), Paragraph("<b>What it Reveals</b>", small)],
        pos_rows, [170, 270]))
    elems.append(sp(6))

    elems.append(Paragraph("Skin Signs - What to Look For", h2))
    skin_rows = [
        ["Peau d'orange",
         "Oedema of skin with deepening of sweat gland/hair follicle openings (orange-peel). Caused by blockage of subcuticular lymphatics by carcinoma cells."],
        ["Dimpling / puckering",
         "Infiltration and shortening of Cooper's ligaments by carcinoma pulling the skin inwards."],
        ["Dilated superficial veins",
         "Cystosarcoma phylloides, rapidly growing sarcoma, acute lacteal duct obstruction."],
        ["Nipple retraction (recent)",
         "Carcinoma extending along lactiferous ducts → fibrosis pulling nipple inward. Lifelong inversion = normal variant."],
        ["Nipple eczema / scaling",
         "Paget's disease of nipple → always biopsy to exclude underlying DCIS or invasive Ca."],
        ["Ulceration / fungation",
         "Advanced carcinoma, Stage IV."],
        ["Satellite skin nodules",
         "Metastatic deposits in skin from underlying carcinoma."],
        ["Redness + warmth",
         "Mastitis; inflammatory (mastitis) carcinoma - do NOT treat as simple mastitis without biopsy."],
    ]
    elems.append(make_table(
        [Paragraph("<b>Sign</b>", small), Paragraph("<b>Significance & Mechanism</b>", small)],
        skin_rows, [120, 320]))

    elems.append(PageBreak())
    return elems

# ─── Page 3: Palpation ────────────────────────────────────────────────────────
def page_palpation():
    elems = []

    elems.append(section_header("03  PALPATION"))
    elems.append(sp(6))

    # Quadrant diagram + technique
    elems.append(Paragraph("Breast Quadrants & Cancer Distribution", h2))

    quad_table = Table(
        [[BreastQuadrantDiagram(180, 180),
          [
            Paragraph("Palpation Technique", h3),
            bp("Position: <b>Sitting → Semi-recumbent (45°) → Supine</b>"),
            bp("Place small pillow under ipsilateral scapula (prevents breast falling laterally)"),
            bp("Use <b>palmar surface of fingers, hand flat</b> (NOT palm, NOT fingertips)"),
            bp("Palpate between pulps of fingers and thumb for a lump"),
            sp(4),
            Paragraph("Systematic Quadrant Check", h3),
            bp("Upper outer quadrant (UOQ) - 50% of cancers here"),
            bp("Upper inner quadrant (UIQ)"),
            bp("Lower outer quadrant (LOQ)"),
            bp("Lower inner quadrant (LIQ)"),
            bp("<b>Retroareolar region</b> (just behind nipple - often missed!)"),
            bp("Axillary tail of Spence"),
          ]]],
        colWidths=[190, 260])
    quad_table.setStyle(TableStyle([
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        ('LEFTPADDING', (0,0), (-1,-1), 4),
    ]))
    elems.append(quad_table)
    elems.append(sp(6))

    elems.append(Paragraph("14-Point Lump Assessment (S Das)", h2))
    palpation_rows = [
        ["1. Site", "Quadrant + distance from nipple in cm"],
        ["2. Size & Shape", "Measure in cm; globular (fibroadenoma) vs irregular (carcinoma)"],
        ["3. Number", "Solitary (Ca, fibroadenoma, cyst) vs multiple bilateral (fibroadenosis)"],
        ["4. Surface", "Smooth (fibroadenoma, cyst) vs irregular/nodular (carcinoma)"],
        ["5. Edge / Margin", "Well-defined (fibroadenoma) vs ill-defined / spiculated (carcinoma)"],
        ["6. Consistency", "Cystic / firm / stony hard (see table below)"],
        ["7. Fluctuation", "Positive in cysts and abscess; tense cyst may be negative"],
        ["8. Transillumination", "Cyst = translucent; solid tumour = opaque; fat = translucent"],
        ["9. Tenderness", "Mastitis, abscess; absent in carcinoma"],
        ["10. Fixity to skin", "Tethering (Cooper's lig.) vs Fixed (direct infiltration)"],
        ["11. Fixity to breast tissue", "Fibroadenoma = freely mobile (Breast Mouse); Carcinoma = fixed"],
        ["12. Fixity to pectoralis major", "Hip-press test (see diagram below)"],
        ["13. Fixity to serratus anterior", "Push-against-wall test for lower outer quadrant lumps"],
        ["14. Fixity to chest wall", "Fixed irrespective of ALL muscle contractions = T4 disease"],
    ]
    elems.append(make_table(
        [Paragraph("<b>#</b>", small), Paragraph("<b>Assessment</b>", small)],
        [[r[0], Paragraph(r[1], small)] for r in palpation_rows],
        [170, 270]))
    elems.append(sp(6))

    elems.append(Paragraph("Consistency - Diagnostic Guide", h2))
    consist_rows = [
        ["Soft, cystic, fluctuant", "Breast cyst, abscess"],
        ["Firm, diffuse India-rubber feel", "Fibroadenosis (mammary dysplasia)"],
        ["Firm, well-encapsulated, smooth", "Fibroadenoma"],
        ["Stony hard, irregular", "Carcinoma (scirrhous) ← most important"],
        ["Variable; huge mass", "Cystosarcoma phylloides / Sarcoma"],
        ["Rubbery, diffuse", "Hashimoto's thyroiditis (if neck) / lymphoma"],
    ]
    elems.append(make_table(
        [Paragraph("<b>Consistency</b>", small), Paragraph("<b>Diagnosis</b>", small)],
        consist_rows, [180, 260]))
    elems.append(sp(6))

    elems.append(Paragraph("Tethering vs Fixation to Skin", h2))
    elems.append(SkinFixityDiagram(width=260, height=130))
    elems.append(sp(4))

    skin_diff = [
        ["Tethering", "Cooper's ligaments infiltrated; lump moves but skin dimples at extremes",
         "T2 stage; moveable lump"],
        ["Fixation", "Direct infiltration of skin; lump and skin move together; skin cannot be pinched",
         "T4 stage; sign of advanced disease"],
    ]
    elems.append(make_table(
        [Paragraph("<b>Type</b>", small), Paragraph("<b>Mechanism</b>", small), Paragraph("<b>Stage</b>", small)],
        skin_diff, [90, 240, 110]))
    elems.append(sp(6))

    elems.append(Paragraph("Pectoralis Major Fixity Test (Hip-Press Test)", h2))
    elems.append(PectoralisFixityDiagram(width=260, height=140))
    elems.append(sp(4))
    elems.append(tip_box("Method: (1) Ask patient to place hand on hip LIGHTLY (muscle relaxed) → assess lump mobility in direction of muscle fibres and at right angles. (2) Now ask her to press hip AS HARD AS POSSIBLE (muscle taut) → reassess. Restricted mobility in line of fibres = fixity to pectoralis major / pectoral fascia."))
    elems.append(sp(6))

    elems.append(Paragraph("Nipple Palpation (Never Skip This!)", h2))
    elems.append(bp("Always palpate tissue just <b>behind the nipple</b> - tumours here are easily missed"))
    elems.append(bp("Move the retro-areolar lump - watch if this causes or increases <b>nipple retraction</b>"))
    elems.append(bp("Gently press: any <b>discharge from a single duct</b> = duct papilloma; from multiple ducts = fibroadenosis"))
    elems.append(bp("Note discharge colour (see discharge table in history section)"))
    elems.append(warning_box("⚠ Any tumour deep to the nipple will be fixed to the nipple, WHETHER IT IS BENIGN OR MALIGNANT, because the main mammary ducts pass through it. Do NOT automatically call this malignant!"))

    elems.append(PageBreak())
    return elems

# ─── Page 4: Axilla + DD + Malignant Features ────────────────────────────────
def page_axilla_dd():
    elems = []

    elems.append(section_header("04  AXILLA EXAMINATION"))
    elems.append(sp(6))

    elems.append(Paragraph("Technique", h2))
    elems.append(bp("<b>Support the patient's arm</b> with your ipsilateral hand to relax the pectoralis and allow deep axillary palpation"))
    elems.append(bp("Use the <b>other hand</b> to palpate deeply into the axilla"))
    elems.append(bp("Assess each node group systematically"))
    elems.append(sp(6))

    axilla_rows = [
        ["Anterior (pectoral)", "Along lower border of pectoralis minor", "Level I; first group involved in breast Ca"],
        ["Central", "Centre of axilla against chest wall", "Most palpable group; Level II"],
        ["Posterior (subscapular)", "Along posterior axillary fold", "Level I"],
        ["Lateral (brachial)", "Along axillary vein", "Level I"],
        ["Apical (infraclavicular)", "Behind clavicle / pectoralis minor", "Level III; indicates advanced disease"],
        ["Supraclavicular", "Angle between SCM and clavicle", "N3 disease; stage IIIC / IV"],
    ]
    elems.append(make_table(
        [Paragraph("<b>Node Group</b>", small), Paragraph("<b>Location</b>", small), Paragraph("<b>Significance</b>", small)],
        axilla_rows, [120, 170, 150]))
    elems.append(sp(4))
    elems.append(tip_box("Always examine BOTH sides - including opposite breast and axilla. Bilateral involvement occurs in ~5% of primary breast cancers."))
    elems.append(sp(8))

    elems.append(section_header("05  DIFFERENTIAL DIAGNOSIS OF A BREAST LUMP"))
    elems.append(sp(6))

    dd_rows = [
        ["Fibroadenoma", "15-35", "Firm, smooth, well-defined", "Highly mobile - 'breast mouse'", "No", "Normal", "No nodes"],
        ["Breast cyst", "30-55", "Cystic / fluctuant", "Mobile", "No", "Normal", "Refills; transilluminates"],
        ["Fibroadenosis", "20-50", "Firm, diffuse, nodular", "Diffuse bilateral", "Yes (cyclical)", "Normal", "Multiple lumps both sides"],
        ["Scirrhous Carcinoma", ">40", "Stony hard, irregular", "Fixed to breast + skin", "No (painless)", "Peau d'orange, dimpling", "Hard axillary nodes"],
        ["Breast abscess", "Lactating", "Fluctuant, tense", "Fixed (inflamed)", "Very tender", "Red, warm, oedema", "Fever, raised WBC"],
        ["Fat necrosis", "Any (trauma)", "Hard, irregular", "May be fixed", "±", "Skin tethering", "History of trauma"],
        ["Cystosarcoma phylloides", ">40", "Variable; huge", "Initially mobile", "No", "Dilated veins; no fixation", "Rapidly growing"],
        ["Duct papilloma", ">30", "Cystic (retroareolar)", "Mobile", "No", "Bloody nipple discharge", "Premalignant"],
        ["Paget's disease", ">50", "Underlying mass ± visible", "Depends", "No", "Nipple eczema/scaling", "Biopsy nipple"],
        ["Gynaecomastia (M)", "Any", "Firm disc, subareolar", "Central", "Tender", "Bilateral", "Exclude hypogonadism"],
    ]
    elems.append(make_table(
        [Paragraph(h, small) for h in ["Condition","Age","Consistency","Mobility","Pain","Skin/Nipple","Other"]],
        [[Paragraph(c if i != 0 else f"<b>{c}</b>", small) for i, c in enumerate(r)] for r in dd_rows],
        [85, 38, 82, 72, 40, 90, 80]))
    elems.append(sp(8))

    elems.append(section_header("06  FEATURES SUGGESTING MALIGNANCY", color=ROSE))
    elems.append(sp(6))

    elems.append(Paragraph("Red Flag Signs on Examination", h2))
    mal_rows = [
        ["Stony hard consistency", "Hallmark of scirrhous/invasive ductal carcinoma; also calcification"],
        ["Irregular, ill-defined margin", "Spiculated lesion = carcinoma until proven otherwise"],
        ["Fixed to breast tissue", "Cannot be moved within breast = invasive carcinoma"],
        ["Skin tethering / dimpling", "Infiltration of Cooper's ligaments"],
        ["Peau d'orange", "Dermal lymphatic blockage by carcinoma"],
        ["Nipple retraction (recent)", "Extension along ducts with fibrosis"],
        ["Nipple ulceration / eczema", "Paget's disease = underlying DCIS/invasive Ca"],
        ["Fixed to pectoral muscle/chest wall", "T3/T4 stage; advanced disease"],
        ["Hard, matted axillary nodes", "Nodal metastases; worst if fixed (N2)"],
        ["Supraclavicular lymphadenopathy", "N3 stage; indicates widespread disease"],
        ["Dilated chest wall veins", "Obstruction of deep veins by tumour"],
        ["Satellite skin nodules", "Cutaneous metastases; cancer en cuirasse"],
        ["Brawny arm oedema", "Axillary vein obstruction by nodes / post-surgery"],
        ["Male patient with hard nodule", "Carcinoma in male (rare but occurs)"],
    ]
    tbl = make_table(
        [Paragraph("<b>Sign</b>", small), Paragraph("<b>Significance</b>", small)],
        mal_rows, [170, 270])
    # Highlight all cells red tinge
    for i in range(1, len(mal_rows)+1):
        tbl.setStyle(TableStyle([('BACKGROUND', (0, i), (0, i), ROSE_LIGHT)]))
    elems.append(tbl)
    elems.append(sp(4))
    elems.append(warning_box("⚠ VIVA TRAP: A YOUNG patient, NO skin fixation, NO lymph node enlargement → STILL DO NOT exclude carcinoma. These classical signs may be absent in early disease. Carcinoma should not be excluded on the basis of young age or absence of nodes alone."))

    elems.append(PageBreak())
    return elems

# ─── Page 5: Investigations + Staging + Q&A ──────────────────────────────────
def page_investigations_staging():
    elems = []

    elems.append(section_header("07  INVESTIGATIONS - TRIPLE ASSESSMENT"))
    elems.append(sp(6))

    elems.append(gold_box("TRIPLE ASSESSMENT = Gold Standard for any breast lump.\n1. Clinical examination  |  2. Imaging (mammogram ± USG)  |  3. Tissue sampling (FNAC or core biopsy)\nAll three results MUST be concordant. If ANY ONE is suspicious → proceed to surgery."))
    elems.append(sp(6))

    inv_rows = [
        ["Mammography", ">35-40 yrs; 2 views (CC + MLO); features: spiculated mass, pleomorphic calcification, skin thickening", "First-line imaging for older women"],
        ["Ultrasound (USG)", "<35 yrs (dense breasts); distinguishes solid vs cystic; guides FNAC/core biopsy", "First-line for younger women"],
        ["MRI Breast", "BRCA carriers; lobular Ca extent; occult primary; implants; pre-BCS planning", "Not routine"],
        ["FNAC", "22-25G needle; cytology only; C1-C5 reporting; quick + cheap", "Cannot distinguish invasive from in-situ"],
        ["Core Needle Biopsy (Tru-cut)", "14-16G; full histology; ER/PR/HER2 status; invasive vs in-situ", "Preferred for preoperative planning"],
        ["Chest X-ray", "Lung metastases; pleural effusion", "Staging"],
        ["CT chest/abdomen/pelvis", "Full staging in confirmed cancer", "Staging"],
        ["Bone scan", "Bone metastases; indicated if bone pain or raised ALP", "Staging"],
        ["Serum CA 15-3, CEA", "Tumour markers; monitor treatment response, NOT diagnosis", "Follow-up"],
        ["ER / PR / HER2", "On core biopsy specimen; determines systemic treatment", "Receptor status"],
    ]
    elems.append(make_table(
        [Paragraph(h, small) for h in ["Investigation", "Details", "When / Note"]],
        inv_rows, [115, 215, 110]))
    elems.append(sp(6))

    elems.append(Paragraph("FNAC Reporting - C-Classification", h2))
    fnac_rows = [
        ["C1", "Non-diagnostic / inadequate", "Repeat FNAC", "—"],
        ["C2", "Benign", "Observe / clinical follow-up", "<3%"],
        ["C3", "Atypical / uncertain", "Repeat or core biopsy", "~10-20%"],
        ["C4", "Suspicious for malignancy", "Core biopsy / proceed", "60-75%"],
        ["C5", "Malignant", "Plan definitive surgery", ">97%"],
    ]
    elems.append(make_table(
        [Paragraph(h, small) for h in ["Class", "Cytology", "Action", "Malignancy Risk"]],
        fnac_rows, [45, 150, 170, 95]))
    elems.append(sp(4))
    elems.append(tip_box("Note: FNAC CANNOT distinguish follicular adenoma from carcinoma in the THYROID, but for BREAST, FNAC CAN suggest malignancy. However, it cannot tell invasive from in-situ cancer - core biopsy is needed for that."))
    elems.append(sp(8))

    elems.append(section_header("08  STAGING OF BREAST CANCER - TNM"))
    elems.append(sp(6))

    tnm_rows = [
        ["T1", "≤2 cm; no fixation; no nipple retraction"],
        ["T2", "2-5 cm; skin may be tethered; no pectoral fixation"],
        ["T3", ">5 cm; skin fixed / ulcerated; pectoral fixation (but not chest wall)"],
        ["T4", "Chest wall fixation; peau d'orange (large area); inflammatory carcinoma"],
        ["N0", "No palpable ipsilateral axillary nodes"],
        ["N1", "Mobile ipsilateral axillary nodes (involved)"],
        ["N2", "Fixed axillary nodes"],
        ["N3", "Supraclavicular / infraclavicular nodes; arm oedema"],
        ["M0", "No distant metastasis"],
        ["M1", "Distant metastasis (bones, lung, liver, brain, ovary)"],
    ]
    tbl = make_table(
        [Paragraph("<b>Stage</b>", small), Paragraph("<b>Description</b>", small)],
        tnm_rows, [60, 380])
    for i, row in enumerate(tnm_rows):
        bg = TEAL_LIGHT if row[0].startswith('T') else (ROSE_LIGHT if row[0].startswith('N') else GOLD_LIGHT)
        tbl.setStyle(TableStyle([('BACKGROUND', (0, i+1), (0, i+1), bg)]))
    elems.append(tbl)
    elems.append(sp(4))

    elems.append(Paragraph("Metastatic Spread from Breast Cancer", h2))
    elems.append(make_table(
        [Paragraph("<b>Route</b>", small), Paragraph("<b>Sites</b>", small)],
        [
            ["Lymphatic", "Axillary nodes (most common) → supraclavicular → internal mammary nodes"],
            ["Blood-borne", "Bones (most common: spine, pelvis, femur, ribs) → Lung → Liver → Brain"],
            ["Transcoelomic", "Ovary (Krukenberg tumour)"],
        ], [90, 350]))
    elems.append(sp(8))

    elems.append(section_header("09  HIGH-YIELD VIVA Q&A"))
    elems.append(sp(6))

    qas = [
        ("Most common site of carcinoma in the breast?",
         "Upper outer quadrant (UOQ) - ~50% of all carcinomas. It contains the greatest volume of breast tissue including the axillary tail."),
        ("What is 'peau d'orange' and its mechanism?",
         "Orange-peel appearance of breast skin. Caused by blockage of subcuticular lymphatics by cancer cells → skin oedema. Hair follicle openings are tethered down and cannot expand → pitting appearance."),
        ("What is Cooper's ligament and what happens when invaded?",
         "Fibrous suspensory septae from breast glandular tissue to overlying skin. Infiltration by carcinoma → ligaments shorten and become inelastic → skin dimpling, puckering, or retraction."),
        ("What is a 'breast mouse'?",
         "A fibroadenoma - highly mobile within the breast, not fixed to skin or deeper structures, slips away from fingers on palpation. Occurs in young women (15-35 yrs)."),
        ("What is Paget's disease of the nipple?",
         "Eczema-like change (scaling, weeping, crusting) of nipple + areola representing extension of underlying DCIS or invasive carcinoma through lactiferous ducts to nipple epidermis. ALWAYS biopsy nipple eczema in women >40 yrs."),
        ("Carcinoma is painless - always true?",
         "PAINLESS AT ONSET - all neoplasms (benign or malignant) are painless initially. Late-stage carcinoma causes bone pain (metastases). Inflammatory carcinoma is a painful exception. Pain must NEVER be used to exclude carcinoma."),
        ("What is the difference between tethering and fixation to skin?",
         "Tethering: Cooper's ligaments invaded; lump still moves a little but skin dimples at extremes (T2). Fixation: direct skin infiltration by tumour; lump and skin move as one unit; skin cannot be pinched up (T4)."),
        ("Fixity to pectoralis major - how tested?",
         "Hip-press test: patient presses hand lightly on hip (relaxed) → test mobility. Then presses AS HARD AS POSSIBLE (taut) → reassess. Restricted movement in the line of muscle fibres = fixed to pectoralis major."),
        ("Most common type of breast cancer?",
         "Invasive Ductal Carcinoma (IDC) / Scirrhous carcinoma - ~75-80% of all breast cancers. Presents as stony hard, irregular, spiculated mass."),
        ("Which breast cancer has the WORST prognosis?",
         "Inflammatory carcinoma (mastitis carcinomatosa) - entire breast red, hot, oedematous; no discrete lump; median survival poor. Also anaplastic (of thyroid equivalent = rapidly fatal); in breast, inflammatory Ca is worst."),
        ("What is Modified Radical Mastectomy (MRM)?",
         "Removal of entire breast + all axillary lymph nodes, preserving BOTH pectoralis major AND minor. This is the standard surgery for breast cancer today, replacing Halsted's radical mastectomy (which removed pectorals). Equal outcomes, less morbidity."),
        ("What is the Sentinel Lymph Node Biopsy (SLNB)?",
         "Injection of radioactive tracer/blue dye near the tumour. First draining (sentinel) node identified and biopsied. If SLNB negative = no further axillary surgery needed. If positive = full axillary dissection."),
    ]

    for q, a in qas:
        row = Table(
            [[Paragraph(f"<b>Q: {q}</b>", Paragraph('', styles['Normal']).__class__.__new__(ParagraphStyle, 'QStyle', fontName='Helvetica-Bold', fontSize=8.5, textColor=TEAL)),
              Paragraph(f"A: {a}", Paragraph('', styles['Normal']).__class__.__new__(ParagraphStyle, 'AStyle', fontName='Helvetica', fontSize=8.5, textColor=DARK))]],
            colWidths=[440]
        )
        q_para = Paragraph(f"<b>Q: {q}</b>", ParagraphStyle('Q', fontName='Helvetica-Bold', fontSize=8.5, textColor=TEAL, spaceAfter=2))
        a_para = Paragraph(f"A: {a}", ParagraphStyle('A', fontName='Helvetica', fontSize=8.5, textColor=DARK, leftIndent=12))
        block = Table([[q_para], [a_para]], colWidths=[440])
        block.setStyle(TableStyle([
            ('BACKGROUND', (0,0), (-1,0), TEAL_LIGHT),
            ('BACKGROUND', (0,1), (-1,1), WHITE),
            ('BOX', (0,0), (-1,-1), 0.8, TEAL),
            ('LEFTPADDING', (0,0), (-1,-1), 8),
            ('RIGHTPADDING', (0,0), (-1,-1), 8),
            ('TOPPADDING', (0,0), (-1,-1), 4),
            ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ]))
        elems.append(block)
        elems.append(sp(4))

    return elems

# ─── Build PDF ────────────────────────────────────────────────────────────────

OUTPUT = "/home/daytona/workspace/breast-exam-pdf/Breast_Examination_Viva_Guide.pdf"

doc = SimpleDocTemplate(
    OUTPUT, pagesize=A4,
    leftMargin=20*mm, rightMargin=20*mm,
    topMargin=30*mm, bottomMargin=18*mm,
    title="Breast Examination - Surgical Viva Guide",
    author="Orris Medical AI",
    subject="Clinical Surgery - Breast"
)

story = []
story += cover_page()
story += page_history_inspection()
story += page_palpation()
story += page_axilla_dd()
story += page_investigations_staging()

doc.build(story, onFirstPage=add_header_footer, onLaterPages=add_header_footer)
print(f"PDF created: {OUTPUT}")
Running Command

cd /home/daytona/workspace/breast-exam-pdf && python create_pdf.py 2>&1

Editing File

~/breast-exam-pdf/create_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/breast-exam-pdf/create_pdf.py'
Running Command

cd /home/daytona/workspace/breast-exam-pdf && python create_pdf.py 2>&1

Editing File

~/breast-exam-pdf/create_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/breast-exam-pdf/create_pdf.py'
Editing File

~/breast-exam-pdf/create_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/breast-exam-pdf/create_pdf.py'
Running Command

cd /home/daytona/workspace/breast-exam-pdf && python create_pdf.py 2>&1

This is a shared conversation. Sign in to Orris to start your own chat.