Guideline to start statin for opd patients

Reading File
Finding Sources
Finding Sources
Searching PubMed

statin therapy initiation guidelines cardiovascular risk

Reading File
Reading File
Finding Sources
Finding Sources
Reading File
Searching the Web

2024 ACC AHA statin guidelines primary prevention OPD outpatient indications

Excellent - I now have strong data from Harrison's 22E (2025), Current Surgical Therapy, and the brand-new 2026 ACC/AHA dyslipidemia guideline. Let me compile the comprehensive answer.

Guidelines for Starting Statin Therapy in Outpatients (OPD)

Based on the 2018 AHA/ACC and updated 2026 ACC/AHA Dyslipidemia Guidelines, along with current textbook evidence from Harrison's 22E (2025), statin initiation is guided by four patient groups:

Group 1: Established ASCVD (Secondary Prevention) - STRONGEST INDICATION

Start HIGH-INTENSITY statin - no risk calculator needed.
Includes any of the following:
  • Acute coronary syndrome (ACS), MI (past or recent)
  • Stable or unstable angina
  • Coronary/peripheral arterial revascularization
  • Ischemic stroke or TIA
  • Peripheral artery disease (PAD), aortic aneurysm
Goal: LDL-C reduction ≥50% (target LDL-C <70 mg/dL; <55 mg/dL if very high risk)
"Patients with clinical ASCVD... are recommended to begin high-intensity statin therapy with an aim of achieving a 50% or greater reduction in LDL-C levels." - Current Surgical Therapy 14e

Group 2: LDL-C ≥190 mg/dL (Familial Hypercholesterolemia or Severe Hypercholesterolemia)

Start HIGH-INTENSITY statin regardless of calculated risk.
  • Treat early, even in young adults
  • Consider additional agents (ezetimibe, PCSK9 inhibitors) if LDL-C target not met
  • Family history should lower threshold for initiation

Group 3: Diabetes Mellitus (Age 40-75) - PRIMARY PREVENTION

Start statin therapy regardless of baseline LDL-C or 10-year risk score.
  • Use moderate-intensity statin as default
  • Escalate to high-intensity if 10-year ASCVD risk ≥10% or other risk factors present
  • In patients <40 or >75 years with DM: use clinical judgment

Group 4: Primary Prevention - Based on 10-Year Cardiovascular Risk (Age 30-79, No ASCVD)

This group requires risk calculator before starting therapy.

2026 Update: Use PREVENT-ASCVD Equations (replaced older Pooled Cohort Equations)

Applies to adults aged 30-79 without known ASCVD or subclinical atherosclerosis, with LDL-C 70-189 mg/dL.
10-Year PREVENT RiskRecommendation
<3%Lifestyle modification only; statin generally not indicated
3% to <5% (borderline)LDL-lowering therapy is reasonable after clinician-patient discussion
5% to <10% (intermediate)Statin recommended after risk discussion
≥10% (high)Statin strongly recommended
Harrison's 22E (2025): "Current guidelines suggest that a 10-year risk >7.5% merits consideration of statin therapy regardless of plasma LDL-C level."

Risk-Enhancing Factors (Tilt Borderline/Intermediate Cases Toward Starting)

When the decision to start is uncertain, these factors push toward initiating therapy:
  • Family history of premature ASCVD (<55 in males, <65 in females)
  • LDL-C ≥160 mg/dL or non-HDL-C ≥190 mg/dL
  • Chronic kidney disease (CKD)
  • Metabolic syndrome
  • Inflammatory conditions (RA, psoriasis, HIV)
  • Premature menopause, pre-eclampsia history
  • Elevated Lp(a) ≥50 mg/dL
  • Elevated hs-CRP ≥2 mg/L
  • Elevated ApoB ≥130 mg/dL
  • Coronary Artery Calcium (CAC) score - men >40, women >50:
    • CAC = 0: consider withholding statin (very low risk)
    • CAC ≥100: favor initiating statin

Statin Intensity Classification

IntensityLDL-C ReductionExamples
High≥50%Atorvastatin 40-80 mg, Rosuvastatin 20-40 mg
Moderate30-49%Atorvastatin 10-20 mg, Rosuvastatin 5-10 mg, Simvastatin 20-40 mg
Low<30%Simvastatin 10 mg, Pravastatin 10-20 mg

Before Starting - Baseline Workup

  1. Fasting lipid panel (LDL-C, HDL-C, TG, total cholesterol)
  2. LFTs (ALT/AST) - baseline, not needed routinely after
  3. CK (baseline if high myopathy risk)
  4. Fasting glucose / HbA1c (statin slightly increases DM risk - counsel patient)
  5. PREVENT-ASCVD 10-year risk calculation (for primary prevention)

Key Points on Safety / Monitoring

  • Routine CK monitoring not needed unless symptoms arise
  • Statin can mildly elevate transaminases - usually transient, not a reason to stop
  • Statin-associated myalgia occurs in ~3-5%; true myopathy is rare
  • Risk of myopathy increases with: advanced age, renal insufficiency, drug interactions (macrolides, antifungals, gemfibrozil, cyclosporine)
  • A small excess risk of new-onset T2DM exists but cardiovascular benefits far outweigh this risk
  • If LDL-C target not met on maximum statin: add ezetimibe first, then consider PCSK9 inhibitor

When NOT to Start (or Use Caution)

  • Active liver disease or persistent unexplained transaminase elevation
  • Pregnancy or breastfeeding (teratogenic - absolutely contraindicated)
  • Rhabdomyolysis history with statins
  • Age >75 years without established ASCVD - individualize (less clear benefit)

Sources: Harrison's Principles of Internal Medicine 22E (2025); Current Surgical Therapy 14e; 2026 ACC/AHA Dyslipidemia Guideline (the most current guideline as of 2026, which introduced PREVENT-ASCVD equations)

Create a statin selection flowchart/decision tree for your clinic

Reading File
Reading File
Running Command

ls /home/daytona/workspace/ 2>/dev/null && mkdir -p /home/daytona/workspace/statin-flowchart

Writing File

~/statin-flowchart/build.js

const pptxgen = require("pptxgenjs");
const pres = new pptxgen();
pres.layout = "LAYOUT_WIDE"; // 13.3 x 7.5 inches

// ── Colour palette ────────────────────────────────────────────────────────────
const C = {
  navy:    "0B2545",   // dominant dark
  teal:    "1B6CA8",   // secondary
  sky:     "4DA6D9",   // light blue accent
  green:   "2E8B57",   // YES / go
  amber:   "D4870A",   // intermediate / caution
  red:     "C0392B",   // high risk / stop
  white:   "FFFFFF",
  offWhite:"F4F8FC",
  grey:    "7F8C8D",
  lightGrey:"E8EFF5",
  yellow:  "FFF3CD",
  darkGrey:"2C3E50",
};

// ── Helper: rounded box ───────────────────────────────────────────────────────
function box(slide, {x, y, w, h, fill, line, lineW, radius, shadow}) {
  slide.addShape(pres.ShapeType.roundRect, {
    x, y, w, h,
    fill: { color: fill || C.white },
    line: { color: line || "CCCCCC", width: lineW || 1 },
    rectRadius: radius !== undefined ? radius : 0.08,
    shadow: shadow || null,
  });
}

// ── Helper: centred label inside a box ───────────────────────────────────────
function label(slide, text, {x, y, w, h, color, fontSize, bold, italic, wrap}) {
  slide.addText(text, {
    x, y, w, h,
    fontSize: fontSize || 11,
    color: color || C.white,
    bold: bold !== undefined ? bold : true,
    italic: italic || false,
    align: "center",
    valign: "middle",
    wrap: wrap !== undefined ? wrap : true,
    margin: 4,
  });
}

// ── Helper: diamond shape ─────────────────────────────────────────────────────
function diamond(slide, {x, y, w, h, fill, line}) {
  // Approximate with rotated rectangle using addShape if available, else use lines
  slide.addShape(pres.ShapeType.diamond, {
    x, y, w, h,
    fill: { color: fill || C.amber },
    line: { color: line || C.navy, width: 1.5 },
  });
}

// ── Helper: arrow connector (horizontal) ─────────────────────────────────────
function arrowH(slide, x1, y, x2, color) {
  slide.addShape(pres.ShapeType.line, {
    x: x1, y, w: x2 - x1, h: 0,
    line: { color: color || C.navy, width: 1.5, endArrowType: "arrow" },
  });
}

// ── Helper: arrow connector (vertical) ───────────────────────────────────────
function arrowV(slide, x, y1, y2, color) {
  slide.addShape(pres.ShapeType.line, {
    x, y: y1, w: 0, h: y2 - y1,
    line: { color: color || C.navy, width: 1.5, endArrowType: "arrow" },
  });
}

function arrowLabel(slide, text, {x, y, fontSize, color}) {
  slide.addText(text, {
    x, y, w: 0.5, h: 0.22,
    fontSize: fontSize || 8,
    color: color || C.green,
    bold: true,
    align: "center",
    margin: 0,
  });
}

// ════════════════════════════════════════════════════════════════════════════
// SLIDE 1 – COVER
// ════════════════════════════════════════════════════════════════════════════
{
  const s = pres.addSlide();

  // Full dark background
  s.addShape(pres.ShapeType.rect, { x:0, y:0, w:13.3, h:7.5, fill:{ color: C.navy } });

  // Decorative teal accent bar (left)
  s.addShape(pres.ShapeType.rect, { x:0, y:0, w:0.18, h:7.5, fill:{ color: C.sky } });

  // Top accent strip
  s.addShape(pres.ShapeType.rect, { x:0.18, y:0, w:13.12, h:0.12, fill:{ color: C.teal } });

  // Main title
  s.addText("Statin Selection", {
    x:0.5, y:1.5, w:12.3, h:1.4,
    fontSize:52, color:C.white, bold:true, align:"center",
    charSpacing:4,
  });

  // Subtitle
  s.addText("Clinical Decision Flowchart for Outpatient Practice", {
    x:0.5, y:3.1, w:12.3, h:0.7,
    fontSize:22, color:C.sky, bold:false, align:"center",
  });

  // Divider line
  s.addShape(pres.ShapeType.line, {
    x:2, y:4.0, w:9.3, h:0,
    line:{ color:C.teal, width:1.5 },
  });

  // Footer info
  s.addText("Based on 2026 ACC/AHA Dyslipidemia Guidelines  |  Harrison's Principles of Internal Medicine 22E", {
    x:0.5, y:4.2, w:12.3, h:0.4,
    fontSize:11, color:C.grey, align:"center",
  });

  // Badge chips
  const badges = ["Primary Prevention", "Secondary Prevention", "Statin Intensity", "Special Populations"];
  badges.forEach((b, i) => {
    const bx = 1.5 + i * 2.7;
    s.addShape(pres.ShapeType.roundRect, {
      x:bx, y:5.0, w:2.3, h:0.38,
      fill:{ color:C.teal }, line:{ color:C.sky, width:1 },
      rectRadius:0.12,
    });
    s.addText(b, {
      x:bx, y:5.0, w:2.3, h:0.38,
      fontSize:9.5, color:C.white, bold:true, align:"center", valign:"middle",
    });
  });

  // Bottom strip
  s.addShape(pres.ShapeType.rect, { x:0, y:7.2, w:13.3, h:0.3, fill:{ color:C.teal } });
  s.addText("OPD / Outpatient Clinic  |  For Educational Use", {
    x:0, y:7.2, w:13.3, h:0.3,
    fontSize:8, color:C.white, align:"center", valign:"middle",
  });
}

// ════════════════════════════════════════════════════════════════════════════
// SLIDE 2 – MAIN FLOWCHART  (landscape decision tree)
// ════════════════════════════════════════════════════════════════════════════
{
  const s = pres.addSlide();

  // Background
  s.addShape(pres.ShapeType.rect, { x:0, y:0, w:13.3, h:7.5, fill:{ color:C.offWhite } });

  // Header bar
  s.addShape(pres.ShapeType.rect, { x:0, y:0, w:13.3, h:0.55, fill:{ color:C.navy } });
  s.addText("STATIN INITIATION DECISION FLOWCHART  — OPD", {
    x:0, y:0, w:13.3, h:0.55,
    fontSize:13, color:C.white, bold:true, align:"center", valign:"middle", charSpacing:2,
  });

  // ── START node ──────────────────────────────────────────────────────────
  const startX=5.65, startY=0.65, startW=2, startH=0.42;
  s.addShape(pres.ShapeType.ellipse, {
    x:startX, y:startY, w:startW, h:startH,
    fill:{ color:C.navy }, line:{ color:C.sky, width:2 },
  });
  s.addText("NEW OPD PATIENT", {
    x:startX, y:startY, w:startW, h:startH,
    fontSize:8.5, color:C.white, bold:true, align:"center", valign:"middle",
  });

  // Arrow: start → Q1
  arrowV(s, 6.65, 1.07, 1.32);

  // ── Q1: Established ASCVD? ───────────────────────────────────────────────
  const q1x=5.3, q1y=1.32, q1w=2.7, q1h=0.62;
  diamond(s, { x:q1x, y:q1y, w:q1w, h:q1h, fill:C.amber, line:C.navy });
  s.addText("Established ASCVD?", {
    x:q1x, y:q1y, w:q1w, h:q1h,
    fontSize:10, color:C.navy, bold:true, align:"center", valign:"middle",
  });

  // YES → left → Secondary Prevention box
  arrowH(s, q1x, q1y + q1h/2, q1x - 0.05, C.green);
  // Arrow going left
  s.addShape(pres.ShapeType.line, {
    x:2.15, y:q1y+q1h/2, w:q1x-2.15, h:0,
    line:{ color:C.green, width:2, endArrowType:"arrow" },
  });
  arrowLabel(s, "YES", { x:2.6, y:q1y+q1h/2-0.22, fontSize:9, color:C.green });

  // ── Box A: Secondary Prevention (HIGH intensity) ──────────────────────
  const ax=0.2, ay=1.1, aw=1.95, ah=1.05;
  s.addShape(pres.ShapeType.roundRect, {
    x:ax, y:ay, w:aw, h:ah,
    fill:{ color:C.red }, line:{ color:"8B0000", width:2 }, rectRadius:0.1,
    shadow:{ type:"outer", color:"00000033", blur:4, offset:2, angle:45 },
  });
  s.addText([
    { text:"HIGH INTENSITY", options:{ breakLine:true, bold:true, fontSize:11, color:C.yellow } },
    { text:"STATIN", options:{ breakLine:true, bold:true, fontSize:11, color:C.white } },
    { text:"Secondary Prevention", options:{ breakLine:false, bold:false, fontSize:8, color:"FFCCCC" } },
  ], { x:ax, y:ay, w:aw, h:ah, align:"center", valign:"middle", margin:4 });

  // Sub-box: ACS labels
  s.addShape(pres.ShapeType.roundRect, {
    x:0.18, y:ay+ah+0.08, w:1.98, h:0.85,
    fill:{ color:"FDF2F2" }, line:{ color:C.red, width:1 }, rectRadius:0.06,
  });
  s.addText([
    { text:"• ACS / MI / Angina\n• Stroke / TIA\n• Revascularization\n• PAD / Aortic Aneurysm", options:{ fontSize:7.5, color:C.darkGrey } },
  ], { x:0.22, y:ay+ah+0.1, w:1.9, h:0.8, valign:"top", margin:3 });

  // Target label
  s.addShape(pres.ShapeType.roundRect, {
    x:0.18, y:ay+ah+0.08+0.85+0.06, w:1.98, h:0.38,
    fill:{ color:"2E8B57" }, line:{ color:"1A5C38", width:1 }, rectRadius:0.06,
  });
  s.addText("Target LDL-C < 70 mg/dL\n(≥50% reduction)", {
    x:0.18, y:ay+ah+0.08+0.85+0.06, w:1.98, h:0.38,
    fontSize:7.5, color:C.white, bold:true, align:"center", valign:"middle",
  });

  // NO → down → Q2
  arrowV(s, 6.65, q1y+q1h, 2.25, C.navy);
  arrowLabel(s, "NO", { x:6.7, y:1.78, fontSize:9, color:C.red });

  // ── Q2: LDL ≥ 190? ───────────────────────────────────────────────────────
  const q2x=5.3, q2y=2.25, q2w=2.7, q2h=0.62;
  diamond(s, { x:q2x, y:q2y, w:q2w, h:q2h, fill:C.amber, line:C.navy });
  s.addText("LDL-C ≥ 190 mg/dL?", {
    x:q2x, y:q2y, w:q2w, h:q2h,
    fontSize:10, color:C.navy, bold:true, align:"center", valign:"middle",
  });

  // YES → right → FH/severe box
  s.addShape(pres.ShapeType.line, {
    x:q2x+q2w, y:q2y+q2h/2, w:11.0-(q2x+q2w), h:0,
    line:{ color:C.red, width:2, endArrowType:"arrow" },
  });
  arrowLabel(s, "YES", { x:9.5, y:q2y+q2h/2-0.22, fontSize:9, color:C.green });

  // ── Box B: FH / Severe (right side) ──────────────────────────────────────
  const bx=11.0, by=1.9, bw=2.1, bh=1.05;
  s.addShape(pres.ShapeType.roundRect, {
    x:bx, y:by, w:bw, h:bh,
    fill:{ color:C.red }, line:{ color:"8B0000", width:2 }, rectRadius:0.1,
    shadow:{ type:"outer", color:"00000033", blur:4, offset:2, angle:45 },
  });
  s.addText([
    { text:"HIGH INTENSITY\n", options:{ bold:true, fontSize:10.5, color:C.yellow, breakLine:true } },
    { text:"STATIN", options:{ bold:true, fontSize:10.5, color:C.white, breakLine:true } },
    { text:"FH / Severe Hyperlipid.", options:{ bold:false, fontSize:7.5, color:"FFCCCC" } },
  ], { x:bx, y:by, w:bw, h:bh, align:"center", valign:"middle", margin:4 });

  s.addShape(pres.ShapeType.roundRect, {
    x:bx, y:by+bh+0.08, w:bw, h:0.7,
    fill:{ color:"FDF2F2" }, line:{ color:C.red, width:1 }, rectRadius:0.06,
  });
  s.addText("• FH (familial hypercholest.)\n• Age-independent\n• Add ezetimibe if needed\n• Consider PCSK9i if LDL ↑↑", {
    x:bx+0.05, y:by+bh+0.1, w:bw-0.1, h:0.65,
    fontSize:7.5, color:C.darkGrey, valign:"top", margin:3,
  });

  // NO → down → Q3
  arrowV(s, 6.65, q2y+q2h, 3.15, C.navy);
  arrowLabel(s, "NO", { x:6.7, y:2.7, fontSize:9, color:C.red });

  // ── Q3: Diabetes (40-75y)? ────────────────────────────────────────────────
  const q3x=5.3, q3y=3.15, q3w=2.7, q3h=0.62;
  diamond(s, { x:q3x, y:q3y, w:q3w, h:q3h, fill:C.amber, line:C.navy });
  s.addText("Diabetes Mellitus\n(Age 40-75 yrs)?", {
    x:q3x, y:q3y, w:q3w, h:q3h,
    fontSize:9.5, color:C.navy, bold:true, align:"center", valign:"middle",
  });

  // YES → left → DM statin box
  s.addShape(pres.ShapeType.line, {
    x:2.85, y:q3y+q3h/2, w:q3x-2.85, h:0,
    line:{ color:C.green, width:2, endArrowType:"arrow" },
  });
  arrowLabel(s, "YES", { x:3.4, y:q3y+q3h/2-0.22, fontSize:9, color:C.green });

  // ── Box C: Diabetes ───────────────────────────────────────────────────────
  const cx=0.85, cy=2.9, cw=2.0, ch=1.0;
  s.addShape(pres.ShapeType.roundRect, {
    x:cx, y:cy, w:cw, h:ch,
    fill:{ color:C.teal }, line:{ color:"104E8B", width:2 }, rectRadius:0.1,
    shadow:{ type:"outer", color:"00000033", blur:4, offset:2, angle:45 },
  });
  s.addText([
    { text:"MODERATE\n", options:{ bold:true, fontSize:11, color:C.white, breakLine:true } },
    { text:"INTENSITY STATIN", options:{ bold:true, fontSize:10, color:C.yellow, breakLine:true } },
    { text:"Diabetes", options:{ bold:false, fontSize:8, color:"CCE5FF" } },
  ], { x:cx, y:cy, w:cw, h:ch, align:"center", valign:"middle", margin:4 });

  s.addShape(pres.ShapeType.roundRect, {
    x:cx, y:cy+ch+0.08, w:cw, h:0.62,
    fill:{ color:"F0F8FF" }, line:{ color:C.teal, width:1 }, rectRadius:0.06,
  });
  s.addText("Escalate to HIGH if:\n10-yr risk ≥10%\nor other risk factors", {
    x:cx+0.05, y:cy+ch+0.1, w:cw-0.1, h:0.58,
    fontSize:7.5, color:C.darkGrey, valign:"top", margin:3,
  });

  // NO → down → Q4 (10-yr risk)
  arrowV(s, 6.65, q3y+q3h, 4.05, C.navy);
  arrowLabel(s, "NO", { x:6.7, y:3.62, fontSize:9, color:C.red });

  // ── Q4: Calculate 10-year ASCVD risk ─────────────────────────────────────
  const q4x=4.9, q4y=4.05, q4w=3.5, q4h=0.68;
  s.addShape(pres.ShapeType.roundRect, {
    x:q4x, y:q4y, w:q4w, h:q4h,
    fill:{ color:C.navy }, line:{ color:C.sky, width:2 }, rectRadius:0.1,
  });
  s.addText("Calculate 10-Year ASCVD Risk\n(PREVENT-ASCVD Equation, Age 30-79)", {
    x:q4x, y:q4y, w:q4w, h:q4h,
    fontSize:9, color:C.white, bold:true, align:"center", valign:"middle",
  });

  // Three branches from Q4
  // Low (<3%) → left
  s.addShape(pres.ShapeType.line, {
    x:1.5, y:q4y+q4h/2, w:q4x-1.5, h:0,
    line:{ color:C.green, width:1.5, endArrowType:"arrow" },
  });
  s.addText("< 3%", {
    x:2.0, y:q4y+q4h/2-0.22, w:1.0, h:0.22,
    fontSize:8, color:C.green, bold:true, align:"center",
  });

  // Intermediate (3-<10%) → down
  arrowV(s, 6.65, q4y+q4h, 5.22, C.amber);
  s.addText("3–<10%\n(discuss)", {
    x:6.68, y:q4y+q4h+0.04, w:0.9, h:0.3,
    fontSize:7.5, color:C.amber, bold:true,
  });

  // High (≥10%) → right
  s.addShape(pres.ShapeType.line, {
    x:q4x+q4w, y:q4y+q4h/2, w:10.8-(q4x+q4w), h:0,
    line:{ color:C.red, width:1.5, endArrowType:"arrow" },
  });
  s.addText("≥ 10%", {
    x:9.1, y:q4y+q4h/2-0.22, w:1.0, h:0.22,
    fontSize:8, color:C.red, bold:true, align:"center",
  });

  // ── Box D: LOW risk (<3%) ──────────────────────────────────────────────────
  const dx=0.18, dy=3.88, dw=1.95, dh=0.78;
  s.addShape(pres.ShapeType.roundRect, {
    x:dx, y:dy, w:dw, h:dh,
    fill:{ color:C.green }, line:{ color:"1A5C38", width:2 }, rectRadius:0.1,
  });
  s.addText("LIFESTYLE\nMODIFICATION\nOnly", {
    x:dx, y:dy, w:dw, h:dh,
    fontSize:9.5, color:C.white, bold:true, align:"center", valign:"middle",
  });
  s.addText("Diet, Exercise,\nNo Statin (typically)\nReassess in 5 yrs", {
    x:dx, y:dy+dh+0.05, w:dw, h:0.48,
    fontSize:7.5, color:C.darkGrey, align:"center", bold:false,
  });

  // ── Box E: INTERMEDIATE risk + risk enhancers ─────────────────────────────
  const ex=5.15, ey=5.22, ew=3.0, eh=0.88;
  s.addShape(pres.ShapeType.roundRect, {
    x:ex, y:ey, w:ew, h:eh,
    fill:{ color:C.amber }, line:{ color:"8B5E00", width:2 }, rectRadius:0.1,
    shadow:{ type:"outer", color:"00000033", blur:4, offset:2, angle:45 },
  });
  s.addText("CHECK RISK ENHANCERS\n& Shared Decision Making", {
    x:ex, y:ey, w:ew, h:eh,
    fontSize:9.5, color:C.white, bold:true, align:"center", valign:"middle",
  });

  // Risk enhancer sub-box
  s.addShape(pres.ShapeType.roundRect, {
    x:4.4, y:ey+eh+0.06, w:4.5, h:0.92,
    fill:{ color:C.yellow }, line:{ color:C.amber, width:1 }, rectRadius:0.08,
  });
  s.addText([
    { text:"Risk Enhancers (any 1 → favour statin):  ", options:{ bold:true, fontSize:8, color:C.navy, breakLine:true } },
    { text:"Fam. hx premature ASCVD  •  LDL ≥160  •  CKD  •  hs-CRP ≥2  •  Lp(a) ≥50  •  ApoB ≥130\nMetabolic syndrome  •  Autoimmune disease (RA/Psoriasis/HIV)  •  Premature menopause / Pre-eclampsia", options:{ bold:false, fontSize:7.5, color:C.darkGrey } },
  ], { x:4.45, y:ey+eh+0.08, w:4.4, h:0.86, valign:"top", margin:4 });

  // CAC sub-box
  s.addShape(pres.ShapeType.roundRect, {
    x:4.4, y:ey+eh+0.06+0.92+0.05, w:4.5, h:0.55,
    fill:{ color:"EAF4FF" }, line:{ color:C.sky, width:1 }, rectRadius:0.08,
  });
  s.addText([
    { text:"Coronary Artery Calcium (CAC):  ", options:{ bold:true, fontSize:8, color:C.navy, breakLine:false } },
    { text:"CAC = 0 → withhold  |  CAC 1–99 → consider  |  CAC ≥100 → INITIATE", options:{ bold:false, fontSize:8, color:C.darkGrey } },
  ], { x:4.45, y:ey+eh+0.06+0.92+0.07, w:4.4, h:0.5, valign:"middle", margin:4 });

  // ── Box F: HIGH risk (≥10%) → moderate/high ───────────────────────────────
  const fx=10.8, fy=3.7, fw=2.35, fh=1.1;
  s.addShape(pres.ShapeType.roundRect, {
    x:fx, y:fy, w:fw, h:fh,
    fill:{ color:C.red }, line:{ color:"8B0000", width:2 }, rectRadius:0.1,
    shadow:{ type:"outer", color:"00000033", blur:4, offset:2, angle:45 },
  });
  s.addText([
    { text:"HIGH / MOD-HIGH\n", options:{ bold:true, fontSize:11, color:C.yellow, breakLine:true } },
    { text:"INTENSITY STATIN", options:{ bold:true, fontSize:10, color:C.white, breakLine:true } },
    { text:"Primary Prevention", options:{ bold:false, fontSize:8, color:"FFCCCC" } },
  ], { x:fx, y:fy, w:fw, h:fh, align:"center", valign:"middle", margin:4 });

  s.addShape(pres.ShapeType.roundRect, {
    x:fx, y:fy+fh+0.06, w:fw, h:0.55,
    fill:{ color:"FDF2F2" }, line:{ color:C.red, width:1 }, rectRadius:0.06,
  });
  s.addText("Target ≥50% LDL-C reduction\nTarget LDL-C <100 mg/dL (primary)", {
    x:fx+0.05, y:fy+fh+0.08, w:fw-0.1, h:0.5,
    fontSize:7.5, color:C.darkGrey, valign:"top", margin:3, bold:false,
  });

  // Footer bar
  s.addShape(pres.ShapeType.rect, { x:0, y:7.22, w:13.3, h:0.28, fill:{ color:C.navy } });
  s.addText("2026 ACC/AHA Dyslipidemia Guideline  |  Harrison's 22E  |  For OPD Use", {
    x:0, y:7.22, w:13.3, h:0.28,
    fontSize:7.5, color:C.grey, align:"center", valign:"middle",
  });
}

// ════════════════════════════════════════════════════════════════════════════
// SLIDE 3 – STATIN INTENSITY TABLE
// ════════════════════════════════════════════════════════════════════════════
{
  const s = pres.addSlide();

  s.addShape(pres.ShapeType.rect, { x:0, y:0, w:13.3, h:7.5, fill:{ color:C.offWhite } });
  s.addShape(pres.ShapeType.rect, { x:0, y:0, w:13.3, h:0.55, fill:{ color:C.navy } });
  s.addText("STATIN INTENSITY GUIDE", {
    x:0, y:0, w:13.3, h:0.55,
    fontSize:15, color:C.white, bold:true, align:"center", valign:"middle", charSpacing:3,
  });

  // Column headers
  const colHeaders = ["Intensity", "LDL-C Reduction", "Statin", "Dose (mg/day)", "Use When"];
  const colX = [0.2, 1.8, 3.6, 6.8, 8.9];
  const colW = [1.5, 1.7, 3.0, 2.0, 4.15];

  // Header row background
  s.addShape(pres.ShapeType.rect, { x:0.2, y:0.65, w:12.9, h:0.4, fill:{ color:C.navy } });
  colHeaders.forEach((h, i) => {
    s.addText(h, {
      x:colX[i], y:0.65, w:colW[i], h:0.4,
      fontSize:10, color:C.white, bold:true, align:"center", valign:"middle",
    });
  });

  // Data rows
  const rows = [
    {
      intensity: "HIGH",
      color: C.red,
      textColor: C.white,
      reduction: "≥ 50%",
      drugs: [
        { drug:"Atorvastatin", doses:"40 mg, 80 mg" },
        { drug:"Rosuvastatin", doses:"20 mg, 40 mg" },
      ],
      uses:"• Established ASCVD (2° prevention)\n• LDL-C ≥190 mg/dL (FH)\n• DM with 10-yr risk ≥10%\n• Primary prevention, 10-yr risk ≥10%",
    },
    {
      intensity: "MODERATE",
      color: C.amber,
      textColor: C.white,
      reduction: "30–49%",
      drugs: [
        { drug:"Atorvastatin", doses:"10 mg, 20 mg" },
        { drug:"Rosuvastatin", doses:"5 mg, 10 mg" },
        { drug:"Simvastatin", doses:"20 mg, 40 mg" },
        { drug:"Pravastatin", doses:"40 mg, 80 mg" },
        { drug:"Lovastatin", doses:"40 mg" },
        { drug:"Fluvastatin", doses:"40 mg BD / 80 mg XL" },
        { drug:"Pitavastatin", doses:"2 mg, 4 mg" },
      ],
      uses:"• DM age 40-75 (first choice)\n• Primary prevention, 3–<10%\n• Elderly (≥75 y) if treatment indicated\n• Statin-intolerant (try lower dose)",
    },
    {
      intensity: "LOW",
      color: C.green,
      textColor: C.white,
      reduction: "< 30%",
      drugs: [
        { drug:"Simvastatin", doses:"10 mg" },
        { drug:"Pravastatin", doses:"10 mg, 20 mg" },
        { drug:"Lovastatin", doses:"20 mg" },
        { drug:"Fluvastatin", doses:"20–40 mg" },
        { drug:"Pitavastatin", doses:"1 mg" },
      ],
      uses:"• Statin intolerance (titrate up)\n• CKD (adjust as needed)\n• Elderly frail patients\n• Drug interaction concern",
    },
  ];

  let rowY = 1.1;
  rows.forEach((row, ri) => {
    const rowH = ri === 1 ? 2.0 : 1.4;
    const altFill = ri % 2 === 0 ? "F9FBFD" : "EDF3FA";

    // Row background
    s.addShape(pres.ShapeType.rect, { x:0.2, y:rowY, w:12.9, h:rowH, fill:{ color:altFill }, line:{ color:"DDDDDD", width:0.5 } });

    // Intensity badge
    s.addShape(pres.ShapeType.roundRect, {
      x:0.25, y:rowY+0.1, w:1.4, h:rowH-0.2,
      fill:{ color:row.color }, line:{ color:row.color, width:1 }, rectRadius:0.1,
    });
    s.addText(row.intensity, {
      x:0.25, y:rowY+0.1, w:1.4, h:rowH-0.2,
      fontSize:11, color:row.textColor, bold:true, align:"center", valign:"middle",
    });

    // Reduction
    s.addText(row.reduction, {
      x:1.85, y:rowY, w:1.65, h:rowH,
      fontSize:12, color:row.color, bold:true, align:"center", valign:"middle",
    });

    // Drugs list
    const drugText = row.drugs.map(d => `${d.drug}  ${d.doses}`).join("\n");
    s.addText(drugText, {
      x:3.65, y:rowY+0.08, w:2.9, h:rowH-0.16,
      fontSize:8.5, color:C.darkGrey, align:"left", valign:"top", margin:4, wrap:true,
    });

    // Doses merged into drug text above
    // Use When
    s.addText(row.uses, {
      x:8.95, y:rowY+0.08, w:4.1, h:rowH-0.16,
      fontSize:8.5, color:C.darkGrey, align:"left", valign:"top", margin:4, wrap:true,
    });

    rowY += rowH + 0.06;
  });

  // Add-on therapy note
  s.addShape(pres.ShapeType.roundRect, {
    x:0.2, y:6.2, w:12.9, h:0.7,
    fill:{ color:"EAF4FF" }, line:{ color:C.sky, width:1.5 }, rectRadius:0.1,
  });
  s.addText([
    { text:"Add-On Therapy if LDL-C target not met on maximum tolerated statin:  ", options:{ bold:true, fontSize:9.5, color:C.navy } },
    { text:"Step 1 → Ezetimibe 10 mg OD  |  Step 2 → PCSK9 Inhibitor (evolocumab / alirocumab) — especially for very high-risk ASCVD or FH", options:{ bold:false, fontSize:9.5, color:C.darkGrey } },
  ], { x:0.3, y:6.22, w:12.7, h:0.65, valign:"middle", margin:5 });

  // Footer
  s.addShape(pres.ShapeType.rect, { x:0, y:7.22, w:13.3, h:0.28, fill:{ color:C.navy } });
  s.addText("2026 ACC/AHA Dyslipidemia Guideline  |  Harrison's 22E  |  For OPD Use", {
    x:0, y:7.22, w:13.3, h:0.28, fontSize:7.5, color:C.grey, align:"center", valign:"middle",
  });
}

// ════════════════════════════════════════════════════════════════════════════
// SLIDE 4 – SPECIAL POPULATIONS + MONITORING
// ════════════════════════════════════════════════════════════════════════════
{
  const s = pres.addSlide();

  s.addShape(pres.ShapeType.rect, { x:0, y:0, w:13.3, h:7.5, fill:{ color:C.offWhite } });
  s.addShape(pres.ShapeType.rect, { x:0, y:0, w:13.3, h:0.55, fill:{ color:C.navy } });
  s.addText("SPECIAL POPULATIONS  &  MONITORING", {
    x:0, y:0, w:13.3, h:0.55,
    fontSize:14, color:C.white, bold:true, align:"center", valign:"middle", charSpacing:2,
  });

  // Left panel: Special Populations
  s.addShape(pres.ShapeType.roundRect, {
    x:0.2, y:0.65, w:6.1, h:6.5,
    fill:{ color:C.white }, line:{ color:C.sky, width:1.5 }, rectRadius:0.1,
  });
  s.addShape(pres.ShapeType.rect, { x:0.2, y:0.65, w:6.1, h:0.42, fill:{ color:C.teal } });
  // Round top corners of header
  s.addText("SPECIAL POPULATIONS", {
    x:0.2, y:0.65, w:6.1, h:0.42,
    fontSize:11, color:C.white, bold:true, align:"center", valign:"middle",
  });

  const populations = [
    { title:"Pregnancy", color:C.red, text:"ABSOLUTELY CONTRAINDICATED\nStop before conception or as soon as detected\n(teratogenic — Category X)" },
    { title:"CKD (non-dialysis)", color:C.teal, text:"Moderate intensity preferred\nRosuvastatin — caution at high doses (renal excretion)\nPravastatin / Fluvastatin — safer options" },
    { title:"Elderly (> 75 yrs)", color:C.amber, text:"Individualize: clear benefit in 2° prevention\nPrimary prevention — shared decision making\nStart low, titrate slowly; monitor CK / LFT" },
    { title:"HIV Patients", color:C.teal, text:"Moderate-to-high intensity statin recommended\nAvoid simvastatin/lovastatin with PIs (high interaction)\nPravastatin or rosuvastatin preferred" },
    { title:"Liver Disease", color:C.red, text:"Active liver disease = CONTRAINDICATED\nMild-moderate hepatic impairment: use with caution\nMonitor LFTs; avoid high-dose statins" },
    { title:"Drug Interactions", color:C.amber, text:"Macrolides, azole antifungals, cyclosporine, gemfibrozil\n→ Avoid co-administration (↑ myopathy risk)\nPravastatin / rosuvastatin lowest interaction" },
  ];

  let py = 1.18;
  populations.forEach(p => {
    s.addShape(pres.ShapeType.roundRect, {
      x:0.35, y:py, w:5.8, h:0.72,
      fill:{ color:C.offWhite }, line:{ color:p.color, width:1.5 }, rectRadius:0.07,
    });
    s.addShape(pres.ShapeType.roundRect, {
      x:0.35, y:py, w:1.35, h:0.72,
      fill:{ color:p.color }, line:{ color:p.color, width:0 }, rectRadius:0.07,
    });
    s.addText(p.title, {
      x:0.35, y:py, w:1.35, h:0.72,
      fontSize:8, color:C.white, bold:true, align:"center", valign:"middle",
    });
    s.addText(p.text, {
      x:1.75, y:py+0.04, w:4.3, h:0.65,
      fontSize:7.5, color:C.darkGrey, align:"left", valign:"top", margin:3, wrap:true,
    });
    py += 0.82;
  });

  // Right panel: Monitoring
  s.addShape(pres.ShapeType.roundRect, {
    x:6.65, y:0.65, w:6.45, h:6.5,
    fill:{ color:C.white }, line:{ color:C.teal, width:1.5 }, rectRadius:0.1,
  });
  s.addShape(pres.ShapeType.rect, { x:6.65, y:0.65, w:6.45, h:0.42, fill:{ color:C.teal } });
  s.addText("MONITORING & FOLLOW-UP", {
    x:6.65, y:0.65, w:6.45, h:0.42,
    fontSize:11, color:C.white, bold:true, align:"center", valign:"middle",
  });

  const monitorItems = [
    {
      icon:"🔬", title:"Baseline Workup (BEFORE starting)",
      steps:["Fasting lipid panel (LDL-C, HDL, TG)", "ALT / AST (baseline LFT)", "Fasting glucose or HbA1c", "CK (if high myopathy risk: elderly, renal, multiple drugs)", "Calculate PREVENT-ASCVD risk score (primary prevention)"],
      color:C.navy,
    },
    {
      icon:"📅", title:"Follow-Up Lipid Panel",
      steps:["4–12 weeks after initiating or changing dose", "Goal: ≥50% reduction (high-intensity) / 30–49% (moderate)", "Annual check thereafter if on target"],
      color:C.teal,
    },
    {
      icon:"💊", title:"Statin Side Effects — When to Act",
      steps:["Myalgia (3-5%): Check CK. Mild → continue; CK >10× ULN → STOP", "Transaminase rise: usually mild/transient; stop if >3× ULN persistent", "New DM: counsel patient — CV benefit outweighs risk", "Routine CK monitoring NOT needed without symptoms"],
      color:C.amber,
    },
    {
      icon:"🔄", title:"If Target NOT Met",
      steps:["Maximise statin dose first", "Add Ezetimibe 10 mg OD (+ ~18% LDL-C reduction)", "Add PCSK9i (evolocumab / alirocumab) for very high risk / FH"],
      color:C.red,
    },
  ];

  let my = 1.18;
  monitorItems.forEach(m => {
    const itemH = m.steps.length * 0.22 + 0.38;
    s.addShape(pres.ShapeType.roundRect, {
      x:6.8, y:my, w:6.15, h:itemH,
      fill:{ color:C.offWhite }, line:{ color:m.color, width:1.5 }, rectRadius:0.07,
    });
    s.addText(m.title, {
      x:6.85, y:my+0.04, w:6.05, h:0.26,
      fontSize:9, color:m.color, bold:true, align:"left", valign:"middle", margin:2,
    });
    m.steps.forEach((step, si) => {
      s.addText("• " + step, {
        x:6.9, y:my+0.3+si*0.21, w:6.0, h:0.21,
        fontSize:7.8, color:C.darkGrey, align:"left", valign:"middle", margin:2, wrap:true,
      });
    });
    my += itemH + 0.1;
  });

  // Footer
  s.addShape(pres.ShapeType.rect, { x:0, y:7.22, w:13.3, h:0.28, fill:{ color:C.navy } });
  s.addText("2026 ACC/AHA Dyslipidemia Guideline  |  Harrison's 22E  |  For OPD Use", {
    x:0, y:7.22, w:13.3, h:0.28, fontSize:7.5, color:C.grey, align:"center", valign:"middle",
  });
}

// ════════════════════════════════════════════════════════════════════════════
// WRITE FILE
// ════════════════════════════════════════════════════════════════════════════
pres.writeFile({ fileName: "/home/daytona/workspace/statin-flowchart/Statin_Decision_Flowchart.pptx" })
  .then(() => console.log("SUCCESS: File written."))
  .catch(e => { console.error("ERROR:", e); process.exit(1); });
Running Command

cd /home/daytona/workspace/statin-flowchart && node build.js 2>&1

Running Command

ls -lh /home/daytona/workspace/statin-flowchart/

Your statin flowchart presentation is ready (164 KB):

Statin Decision Flowchart

Presentation · PPTX


Here is what is included across the 4 slides:
Slide 1 - Cover Dark navy/teal professional design with title, subtitle, and topic badges.
Slide 2 - Main Decision Flowchart A colour-coded step-by-step decision tree flowing from "New OPD Patient" through:
  1. Established ASCVD? → High-intensity statin (red box, secondary prevention)
  2. LDL-C ≥190 mg/dL? → High-intensity statin (FH / severe)
  3. Diabetes age 40-75? → Moderate-intensity statin
  4. Calculate 10-year PREVENT-ASCVD risk → three branches:
    • <3% → Lifestyle modification only (green)
    • 3-<10% → Check risk enhancers + shared decision making (amber), with CAC scoring guide
    • ≥10% → High/mod-high intensity statin (red)
Slide 3 - Statin Intensity Table Colour-banded table with HIGH / MODERATE / LOW intensity rows showing:
  • LDL-C reduction %, drug names, doses, and clinical indications
  • Add-on therapy strip (ezetimibe → PCSK9i) at the bottom
Slide 4 - Special Populations & Monitoring Side-by-side panels covering:
  • Pregnancy, CKD, elderly, HIV, liver disease, drug interactions
  • Baseline workup, follow-up lipid panel timing, side effect management, and escalation ladder

Generate a quick-reference pocket card PDF from this flowchart

Reading File
Writing File

~/statin-flowchart/pocket_card.py

"""
Statin Selection Quick-Reference Pocket Card
Size: 3.5 x 8.5 inches (tall card, 2 pages = front/back)
"""
from reportlab.lib.pagesizes import inch
from reportlab.lib import colors
from reportlab.lib.colors import HexColor
from reportlab.platypus import SimpleDocTemplate
from reportlab.pdfgen import canvas
from reportlab.lib.utils import simpleSplit
import math

# ── Page size ─────────────────────────────────────────────────────────────────
W, H = 3.5 * inch, 8.5 * inch

# ── Palette ───────────────────────────────────────────────────────────────────
NAVY    = HexColor("#0B2545")
TEAL    = HexColor("#1B6CA8")
SKY     = HexColor("#4DA6D9")
GREEN   = HexColor("#2E8B57")
AMBER   = HexColor("#D4870A")
RED     = HexColor("#C0392B")
YELLOW  = HexColor("#FFF3CD")
OFFWHITE= HexColor("#F4F8FC")
WHITE   = colors.white
DGREY   = HexColor("#2C3E50")
LGREY   = HexColor("#ECF0F1")
MGREY   = HexColor("#7F8C8D")

OUTPUT = "/home/daytona/workspace/statin-flowchart/Statin_Pocket_Card.pdf"

# ── Canvas helpers ─────────────────────────────────────────────────────────────
def rounded_rect(c, x, y, w, h, r=4, fill=None, stroke=None, stroke_w=0.75):
    c.saveState()
    if fill:
        c.setFillColor(fill)
    if stroke:
        c.setStrokeColor(stroke)
        c.setLineWidth(stroke_w)
    else:
        c.setLineWidth(0)
    c.roundRect(x, y, w, h, r, fill=1 if fill else 0, stroke=1 if stroke else 0)
    c.restoreState()

def rect(c, x, y, w, h, fill=None, stroke=None, stroke_w=0.5):
    c.saveState()
    if fill:  c.setFillColor(fill)
    if stroke: c.setStrokeColor(stroke); c.setLineWidth(stroke_w)
    c.rect(x, y, w, h, fill=1 if fill else 0, stroke=1 if stroke else 0)
    c.restoreState()

def text(c, txt, x, y, size=7, color=DGREY, bold=False, align="left", max_w=None):
    c.saveState()
    c.setFillColor(color)
    face = "Helvetica-Bold" if bold else "Helvetica"
    c.setFont(face, size)
    if align == "center" and max_w:
        c.drawCentredString(x + max_w / 2, y, txt)
    elif align == "right" and max_w:
        c.drawRightString(x + max_w, y, txt)
    else:
        c.drawString(x, y, txt)
    c.restoreState()

def multiline(c, txt, x, y, size=6.5, color=DGREY, bold=False, max_w=None, line_h=9):
    """Wrap and draw multi-line text. Returns final y."""
    face = "Helvetica-Bold" if bold else "Helvetica"
    mw = max_w or (W - x - 6)
    lines = simpleSplit(txt, face, size, mw)
    cy = y
    c.saveState()
    c.setFillColor(color)
    c.setFont(face, size)
    for line in lines:
        c.drawString(x, cy, line)
        cy -= line_h
    c.restoreState()
    return cy

def section_header(c, title, y, bg=NAVY, text_color=WHITE, h=13):
    rect(c, 4, y, W-8, h, fill=bg)
    text(c, title, 4, y + 3.5, size=7, color=text_color, bold=True, align="center", max_w=W-8)
    return y - h - 2

def arrow_down(c, x, y, length=8):
    c.saveState()
    c.setStrokeColor(NAVY)
    c.setLineWidth(0.8)
    c.line(x, y, x, y - length)
    # arrowhead
    c.setFillColor(NAVY)
    p = c.beginPath()
    p.moveTo(x - 3, y - length + 3)
    p.lineTo(x, y - length)
    p.lineTo(x + 3, y - length + 3)
    p.close()
    c.drawPath(p, fill=1, stroke=0)
    c.restoreState()

def diamond_node(c, cx, cy, hw, hh, fill=AMBER, stroke=NAVY, label="", label_size=6.5):
    """Draw diamond centred at (cx, cy)."""
    c.saveState()
    c.setFillColor(fill)
    c.setStrokeColor(stroke)
    c.setLineWidth(0.8)
    p = c.beginPath()
    p.moveTo(cx, cy + hh)      # top
    p.lineTo(cx + hw, cy)      # right
    p.lineTo(cx, cy - hh)      # bottom
    p.lineTo(cx - hw, cy)      # left
    p.close()
    c.drawPath(p, fill=1, stroke=1)
    c.restoreState()
    # label
    lines = simpleSplit(label, "Helvetica-Bold", label_size, hw * 1.8)
    total = len(lines) * (label_size + 1)
    sy = cy + total / 2 - label_size + 1
    c.saveState()
    c.setFillColor(NAVY)
    c.setFont("Helvetica-Bold", label_size)
    for ln in lines:
        c.drawCentredString(cx, sy, ln)
        sy -= label_size + 1
    c.restoreState()

def outcome_box(c, x, y, w, h, bg, title, sub, r=5):
    rounded_rect(c, x, y, w, h, r=r, fill=bg)
    # title
    c.saveState()
    c.setFillColor(WHITE)
    c.setFont("Helvetica-Bold", 6.5)
    c.drawCentredString(x + w/2, y + h - 10, title)
    c.setFont("Helvetica", 5.8)
    c.setFillColor(HexColor("#EEEEEE"))
    lines = simpleSplit(sub, "Helvetica", 5.8, w - 6)
    ty = y + h - 20
    for ln in lines:
        c.drawCentredString(x + w/2, ty, ln)
        ty -= 8
    c.restoreState()

# ══════════════════════════════════════════════════════════════════════════════
# PAGE 1 — FRONT (Decision Flowchart)
# ══════════════════════════════════════════════════════════════════════════════
def draw_front(c):
    margin = 6
    cw = W - 2 * margin  # content width

    # Background
    rect(c, 0, 0, W, H, fill=OFFWHITE)

    # Header
    rect(c, 0, H - 38, W, 38, fill=NAVY)
    c.saveState()
    c.setFillColor(SKY)
    c.setFont("Helvetica-Bold", 9.5)
    c.drawCentredString(W/2, H - 15, "STATIN SELECTION")
    c.setFont("Helvetica", 7)
    c.setFillColor(WHITE)
    c.drawCentredString(W/2, H - 26, "Quick-Reference Pocket Card")
    c.setFont("Helvetica", 5.5)
    c.setFillColor(MGREY)
    c.drawCentredString(W/2, H - 35, "2026 ACC/AHA Guideline  |  Harrison's 22E")
    c.restoreState()

    # Accent bar
    rect(c, 0, H - 40, W, 2, fill=TEAL)

    cy = H - 50  # current y (top of content)

    # START pill
    rounded_rect(c, margin+20, cy-14, cw-40, 14, r=7, fill=NAVY)
    text(c, "NEW OPD PATIENT", margin+20, cy-10, size=6.5, color=WHITE, bold=True,
         align="center", max_w=cw-40)
    cy -= 16

    # Arrow down
    arrow_down(c, W/2, cy, 8)
    cy -= 11

    # ── Decision 1: Established ASCVD? ──────────────────────────────────────
    diam_cx = W/2
    diam_hw = 58
    diam_hh = 17
    dcy = cy - diam_hh
    diamond_node(c, diam_cx, dcy, diam_hw, diam_hh, fill=HexColor("#FEF3C7"), stroke=AMBER,
                 label="Established ASCVD?", label_size=6.5)

    # YES → left
    c.saveState()
    c.setStrokeColor(GREEN); c.setLineWidth(0.8)
    c.line(diam_cx - diam_hw, dcy, margin, dcy)
    # arrowhead left
    c.setFillColor(GREEN)
    p = c.beginPath()
    p.moveTo(margin+4, dcy+3); p.lineTo(margin, dcy); p.lineTo(margin+4, dcy-3); p.close()
    c.drawPath(p, fill=1, stroke=0)
    c.restoreState()
    text(c, "YES", margin+1, dcy+2.5, size=5.5, color=GREEN, bold=True)

    # NO → down
    c.saveState(); c.setStrokeColor(NAVY); c.setLineWidth(0.8)
    c.line(diam_cx, dcy-diam_hh, diam_cx, dcy-diam_hh-7)
    c.restoreState()
    text(c, "NO", W/2+1, dcy-diam_hh-2, size=5.5, color=RED, bold=True)

    # LEFT BOX: 2° Prevention
    bh = 30
    outcome_box(c, margin, dcy-bh+8, 45, bh, bg=RED,
                title="HIGH INTENSITY",
                sub="2° Prevention\nTarget LDL<70")

    cy = dcy - diam_hh - 10

    # ── Decision 2: LDL-C ≥190? ─────────────────────────────────────────────
    dcy2 = cy - diam_hh
    diamond_node(c, diam_cx, dcy2, diam_hw, diam_hh, fill=HexColor("#FEF3C7"), stroke=AMBER,
                 label="LDL-C ≥190 mg/dL?", label_size=6.5)

    # YES → right
    c.saveState()
    c.setStrokeColor(RED); c.setLineWidth(0.8)
    c.line(diam_cx + diam_hw, dcy2, W-margin, dcy2)
    c.setFillColor(RED)
    p = c.beginPath()
    p.moveTo(W-margin-4, dcy2+3); p.lineTo(W-margin, dcy2); p.lineTo(W-margin-4, dcy2-3); p.close()
    c.drawPath(p, fill=1, stroke=0)
    c.restoreState()
    text(c, "YES", W-margin-20, dcy2+2.5, size=5.5, color=GREEN, bold=True)

    # NO → down
    c.saveState(); c.setStrokeColor(NAVY); c.setLineWidth(0.8)
    c.line(diam_cx, dcy2-diam_hh, diam_cx, dcy2-diam_hh-7)
    c.restoreState()
    text(c, "NO", W/2+1, dcy2-diam_hh-2, size=5.5, color=RED, bold=True)

    # RIGHT BOX: FH
    outcome_box(c, W-margin-45, dcy2-22+8, 45, 30, bg=RED,
                title="HIGH INTENSITY",
                sub="FH/Severe\nAdd ezetimibe")

    cy = dcy2 - diam_hh - 10

    # ── Decision 3: Diabetes 40-75y? ────────────────────────────────────────
    dcy3 = cy - diam_hh
    diamond_node(c, diam_cx, dcy3, diam_hw, diam_hh, fill=HexColor("#FEF3C7"), stroke=AMBER,
                 label="DM age 40-75 yrs?", label_size=6.5)

    # YES → left
    c.saveState()
    c.setStrokeColor(GREEN); c.setLineWidth(0.8)
    c.line(diam_cx - diam_hw, dcy3, margin, dcy3)
    c.setFillColor(GREEN)
    p = c.beginPath()
    p.moveTo(margin+4, dcy3+3); p.lineTo(margin, dcy3); p.lineTo(margin+4, dcy3-3); p.close()
    c.drawPath(p, fill=1, stroke=0)
    c.restoreState()
    text(c, "YES", margin+1, dcy3+2.5, size=5.5, color=GREEN, bold=True)

    # NO → down
    c.saveState(); c.setStrokeColor(NAVY); c.setLineWidth(0.8)
    c.line(diam_cx, dcy3-diam_hh, diam_cx, dcy3-diam_hh-7)
    c.restoreState()
    text(c, "NO", W/2+1, dcy3-diam_hh-2, size=5.5, color=RED, bold=True)

    # LEFT BOX: DM
    outcome_box(c, margin, dcy3-22+8, 45, 30, bg=TEAL,
                title="MOD INTENSITY",
                sub="Diabetes\n↑ if risk ≥10%")

    cy = dcy3 - diam_hh - 10

    # ── PREVENT Risk score box ───────────────────────────────────────────────
    rounded_rect(c, margin, cy-22, cw, 22, r=5, fill=NAVY)
    text(c, "Calculate PREVENT-ASCVD 10-yr Risk", margin, cy-11,
         size=6.5, color=WHITE, bold=True, align="center", max_w=cw)
    text(c, "(Age 30-79, no known ASCVD, LDL 70-189)", margin, cy-20,
         size=5.8, color=SKY, bold=False, align="center", max_w=cw)

    arrow_down(c, W/2, cy-23, 8)
    cy -= 34

    # ── Three risk branches ──────────────────────────────────────────────────
    branch_y = cy - 2
    bw = (cw - 6) / 3
    bh2 = 40

    # Draw horizontal line
    c.saveState(); c.setStrokeColor(NAVY); c.setLineWidth(0.7)
    c.line(margin + bw/2, branch_y, W - margin - bw/2, branch_y)
    # Left branch arrow
    c.line(margin + bw/2, branch_y, margin + bw/2, branch_y - 8)
    # Mid branch arrow (already had vertical)
    c.line(W/2, branch_y, W/2, branch_y - 8)
    # Right branch arrow
    c.line(W - margin - bw/2, branch_y, W - margin - bw/2, branch_y - 8)
    c.restoreState()

    # LEFT: <3%
    rounded_rect(c, margin, branch_y - 8 - bh2, bw, bh2, r=4, fill=GREEN)
    c.saveState()
    c.setFillColor(WHITE); c.setFont("Helvetica-Bold", 6.5)
    c.drawCentredString(margin + bw/2, branch_y - 18, "< 3%")
    c.setFont("Helvetica", 5.5); c.setFillColor(HexColor("#CCFFCC"))
    c.drawCentredString(margin + bw/2, branch_y - 27, "Lifestyle")
    c.drawCentredString(margin + bw/2, branch_y - 35, "Only")
    c.drawCentredString(margin + bw/2, branch_y - 43, "No statin")
    c.restoreState()

    # MID: 3-<10%
    rounded_rect(c, margin + bw + 3, branch_y - 8 - bh2, bw, bh2, r=4, fill=AMBER)
    c.saveState()
    c.setFillColor(WHITE); c.setFont("Helvetica-Bold", 6.5)
    c.drawCentredString(margin + bw + 3 + bw/2, branch_y - 18, "3-<10%")
    c.setFont("Helvetica", 5.5); c.setFillColor(YELLOW)
    c.drawCentredString(margin + bw + 3 + bw/2, branch_y - 27, "Shared")
    c.drawCentredString(margin + bw + 3 + bw/2, branch_y - 35, "Decision")
    c.drawCentredString(margin + bw + 3 + bw/2, branch_y - 43, "MOD statin")
    c.restoreState()

    # RIGHT: ≥10%
    rounded_rect(c, W - margin - bw, branch_y - 8 - bh2, bw, bh2, r=4, fill=RED)
    c.saveState()
    c.setFillColor(WHITE); c.setFont("Helvetica-Bold", 6.5)
    c.drawCentredString(W - margin - bw/2, branch_y - 18, "≥ 10%")
    c.setFont("Helvetica", 5.5); c.setFillColor(HexColor("#FFCCCC"))
    c.drawCentredString(W - margin - bw/2, branch_y - 27, "HIGH")
    c.drawCentredString(W - margin - bw/2, branch_y - 35, "intensity")
    c.drawCentredString(W - margin - bw/2, branch_y - 43, "statin")
    c.restoreState()

    cy = branch_y - 8 - bh2 - 5

    # ── Risk Enhancers strip ────────────────────────────────────────────────
    eh = 42
    rounded_rect(c, margin, cy-eh, cw, eh, r=4, fill=HexColor("#FFF8E1"), stroke=AMBER, stroke_w=0.8)
    text(c, "RISK ENHANCERS (push 3-<10% toward statin):", margin+3, cy-9,
         size=6, color=AMBER, bold=True)
    enhancers = [
        "Fam hx premature ASCVD  •  LDL ≥160  •  hs-CRP ≥2",
        "Lp(a) ≥50  •  ApoB ≥130  •  CKD  •  Metabolic Synd.",
        "RA / Psoriasis / HIV  •  Pre-eclampsia / Early menopause",
        "CAC=0 → withhold  |  CAC ≥100 → initiate statin",
    ]
    ey2 = cy - 18
    for line in enhancers:
        text(c, line, margin+3, ey2, size=5.8, color=DGREY)
        ey2 -= 8.5

    cy -= eh + 4

    # ── Footer ──────────────────────────────────────────────────────────────
    rect(c, 0, 0, W, 16, fill=NAVY)
    text(c, "See reverse for: Statin Doses  |  Monitoring  |  Special Populations",
         margin, 10, size=5.5, color=SKY, bold=False, align="center", max_w=cw)
    text(c, "ACC/AHA 2026  |  Harrison's 22E",
         margin, 3, size=5, color=MGREY, align="center", max_w=cw)


# ══════════════════════════════════════════════════════════════════════════════
# PAGE 2 — BACK (Statin doses + Monitoring + Special populations)
# ══════════════════════════════════════════════════════════════════════════════
def draw_back(c):
    margin = 6
    cw = W - 2 * margin

    rect(c, 0, 0, W, H, fill=OFFWHITE)

    # Header
    rect(c, 0, H - 28, W, 28, fill=TEAL)
    text(c, "STATIN DOSES & MONITORING", margin, H-11, size=8,
         color=WHITE, bold=True, align="center", max_w=cw)
    text(c, "Pocket Reference  —  Back", margin, H-22, size=6,
         color=HexColor("#CCE5FF"), align="center", max_w=cw)
    rect(c, 0, H-30, W, 2, fill=SKY)

    cy = H - 38

    # ── Intensity table header ───────────────────────────────────────────────
    rect(c, margin, cy-11, cw, 11, fill=NAVY)
    cols = [6, 52, 110, 165]  # x positions
    hdrs = ["LEVEL", "DRUG", "DOSE (mg)", "LDL↓"]
    for i, h in enumerate(hdrs):
        text(c, h, cols[i]+margin, cy-8, size=5.8, color=WHITE, bold=True)
    cy -= 11

    # Table data
    rows = [
        # (level, color, drug, dose, reduction)
        ("HIGH",   RED,   "Atorvastatin",  "40, 80",    "≥50%"),
        ("HIGH",   RED,   "Rosuvastatin",  "20, 40",    "≥50%"),
        ("MOD",    AMBER, "Atorvastatin",  "10, 20",    "30-49%"),
        ("MOD",    AMBER, "Rosuvastatin",  "5, 10",     "30-49%"),
        ("MOD",    AMBER, "Simvastatin",   "20, 40",    "30-49%"),
        ("MOD",    AMBER, "Pravastatin",   "40, 80",    "30-49%"),
        ("MOD",    AMBER, "Pitavastatin",  "2, 4",      "30-49%"),
        ("LOW",    GREEN, "Simvastatin",   "10",        "<30%"),
        ("LOW",    GREEN, "Pravastatin",   "10, 20",    "<30%"),
        ("LOW",    GREEN, "Fluvastatin",   "20-40",     "<30%"),
    ]
    for i, (lvl, col, drug, dose, red) in enumerate(rows):
        row_bg = WHITE if i % 2 == 0 else HexColor("#EDF3FA")
        rect(c, margin, cy-10, cw, 10, fill=row_bg)
        # Level badge
        rounded_rect(c, margin+1, cy-9, 46, 8.5, r=2, fill=col)
        c.saveState()
        c.setFillColor(WHITE); c.setFont("Helvetica-Bold", 5.5)
        c.drawCentredString(margin+24, cy-3.5, lvl)
        c.restoreState()
        text(c, drug, cols[1]+margin, cy-7.5, size=6, color=DGREY)
        text(c, dose, cols[2]+margin, cy-7.5, size=6, color=DGREY)
        text(c, red,  cols[3]+margin, cy-7.5, size=6, color=col, bold=True)
        cy -= 10

    # Divider
    rect(c, margin, cy-1, cw, 1, fill=TEAL)
    cy -= 4

    # ── Add-on therapy ────────────────────────────────────────────────────────
    rounded_rect(c, margin, cy-22, cw, 22, r=4, fill=HexColor("#EAF4FF"), stroke=SKY, stroke_w=0.8)
    text(c, "ADD-ON THERAPY (if LDL target not met):", margin+3, cy-9,
         size=6.5, color=TEAL, bold=True)
    text(c, "Step 1: Ezetimibe 10 mg OD  (+18% LDL reduction)", margin+3, cy-17.5,
         size=6, color=DGREY)
    text(c, "Step 2: PCSK9 inhibitor (evolocumab / alirocumab)", margin+3, cy-25,
         size=6, color=DGREY)
    cy -= 26

    # ── Monitoring ────────────────────────────────────────────────────────────
    rect(c, margin, cy-11, cw, 11, fill=NAVY)
    text(c, "MONITORING", margin, cy-8, size=7, color=WHITE, bold=True,
         align="center", max_w=cw)
    cy -= 11

    monitor_items = [
        ("Before starting:", "Lipid panel, ALT/AST, Fasting glucose, CK (if high risk)", TEAL),
        ("4-12 wks after:", "Repeat fasting lipid panel; check % LDL-C reduction", TEAL),
        ("Myalgia (3-5%):", "Check CK. CK >10× ULN → STOP statin", AMBER),
        ("Transaminase ↑:", "Usually mild/transient. Stop if >3× ULN persistent", AMBER),
        ("New DM risk:", "Counsel: CV benefit far outweighs DM risk", GREEN),
        ("Routine CK:", "NOT needed unless symptoms arise", GREEN),
    ]
    for (label_t, detail, col) in monitor_items:
        bg = WHITE
        rect(c, margin, cy-16, cw, 16, fill=bg, stroke=LGREY, stroke_w=0.3)
        rounded_rect(c, margin+1, cy-15, 52, 13, r=2, fill=col)
        c.saveState()
        c.setFillColor(WHITE); c.setFont("Helvetica-Bold", 5.5)
        lines = simpleSplit(label_t, "Helvetica-Bold", 5.5, 50)
        ly = cy - 8
        for l in lines:
            c.drawCentredString(margin+27, ly, l)
            ly -= 7
        c.restoreState()
        multiline(c, detail, margin+56, cy-8, size=5.8, color=DGREY,
                  max_w=cw-50, line_h=7.5)
        cy -= 16

    # ── Special Populations ─────────────────────────────────────────────────
    rect(c, margin, cy-11, cw, 11, fill=NAVY)
    text(c, "SPECIAL POPULATIONS", margin, cy-8, size=7, color=WHITE, bold=True,
         align="center", max_w=cw)
    cy -= 11

    sp_items = [
        ("PREGNANCY",         "CONTRAINDICATED — stop immediately", RED),
        ("CKD",               "Moderate intensity preferred; pravastatin/fluvastatin safer", TEAL),
        ("ELDERLY >75y",      "2° prevention: continue; 1° prevention: individualize", AMBER),
        ("HIV",               "Avoid simvastatin with PIs; use pravastatin/rosuvastatin", TEAL),
        ("LIVER DISEASE",     "Active disease = CONTRAINDICATED; caution in mild/mod", RED),
        ("DRUG INTERACTIONS", "Macrolides, azoles, gemfibrozil ↑ myopathy risk", AMBER),
    ]
    for (sp_label, detail, col) in sp_items:
        rect(c, margin, cy-14, cw, 14, fill=WHITE, stroke=LGREY, stroke_w=0.3)
        rounded_rect(c, margin+1, cy-13, 52, 12, r=2, fill=col)
        c.saveState()
        c.setFillColor(WHITE); c.setFont("Helvetica-Bold", 5)
        lines = simpleSplit(sp_label, "Helvetica-Bold", 5, 50)
        ly = cy - 7
        for l in lines:
            c.drawCentredString(margin+27, ly, l)
            ly -= 6
        c.restoreState()
        multiline(c, detail, margin+56, cy-7, size=5.5, color=DGREY,
                  max_w=cw-52, line_h=7)
        cy -= 14

    # ── LDL targets quick ref ────────────────────────────────────────────────
    th = 28
    rounded_rect(c, margin, cy-th, cw, th, r=4, fill=NAVY, stroke=SKY, stroke_w=0.8)
    text(c, "LDL-C TARGETS", margin, cy-9, size=6.5, color=SKY, bold=True,
         align="center", max_w=cw)
    targets = [
        "2° Prevention (very high risk): < 55 mg/dL  (≥50% reduction)",
        "2° Prevention:  < 70 mg/dL  (≥50% reduction)",
        "1° Prevention (high risk):  < 100 mg/dL",
        "1° Prevention (mod risk):   LDL reduction 30-49%",
    ]
    ty2 = cy - 18
    for t in targets:
        text(c, t, margin+3, ty2, size=5.5, color=WHITE)
        ty2 -= 7.5
    cy -= th + 3

    # Footer
    rect(c, 0, 0, W, 14, fill=TEAL)
    text(c, "2026 ACC/AHA Dyslipidemia Guideline  |  Harrison's 22E (2025)",
         margin, 9, size=5.5, color=WHITE, align="center", max_w=cw)
    text(c, "For educational use in outpatient clinical practice",
         margin, 2, size=5, color=HexColor("#CCE5FF"), align="center", max_w=cw)


# ══════════════════════════════════════════════════════════════════════════════
# RENDER
# ══════════════════════════════════════════════════════════════════════════════
c = canvas.Canvas(OUTPUT, pagesize=(W, H))
c.setTitle("Statin Selection — Quick Reference Pocket Card")
c.setAuthor("Orris Clinical Tools")
c.setSubject("Statin initiation guidelines 2026")

draw_front(c)
c.showPage()
draw_back(c)
c.showPage()
c.save()
print("SUCCESS:", OUTPUT)
Running Command

cd /home/daytona/workspace/statin-flowchart && python pocket_card.py 2>&1

Running Command

ls -lh /home/daytona/workspace/statin-flowchart/Statin_Pocket_Card.pdf

Your pocket card is ready:

Statin Pocket Card

PDF Document · PDF


Format: 3.5 × 8.5 inches (standard tall wallet/pocket card), 2 pages — print double-sided and fold.
Page 1 - FRONT (Decision Flowchart)
  • Start node → 4 sequential diamond decision nodes
  • Branch 1: Established ASCVD? → High-intensity statin (red)
  • Branch 2: LDL-C ≥190? → High-intensity statin / FH (red, right)
  • Branch 3: DM age 40-75? → Moderate-intensity statin (teal, left)
  • Branch 4: PREVENT-ASCVD 10-yr risk → 3-column split: <3% (green/lifestyle), 3-<10% (amber/discuss), ≥10% (red/high statin)
  • Risk enhancer strip at bottom (Lp(a), hs-CRP, CAC, CKD, etc.)
Page 2 - BACK (Reference tables)
  • Statin intensity table: HIGH / MOD / LOW with all drug names and doses
  • Add-on therapy ladder: ezetimibe → PCSK9 inhibitor
  • Monitoring section: before starting, 4-12 week follow-up, myalgia/transaminase rules
  • Special populations: pregnancy, CKD, elderly, HIV, liver disease, drug interactions
  • LDL-C targets quick reference box
This is a shared conversation. Sign in to Orris to start your own chat.