Guidelines for using statins
"statin" AND "guidelines" AND "cardiovascular"
statin therapy guidelines 2024 2025 ACC AHA indications intensity
PMID: 41824590
https://www.tctmd.com/news/lower-ldl-levels-starting-earlier…
| Intensity | LDL-C Reduction | Examples |
|---|---|---|
| High | ≥50% | Atorvastatin 40-80 mg, Rosuvastatin 20-40 mg |
| Moderate | 30-49% | Atorvastatin 10-20 mg, Rosuvastatin 5-10 mg, Simvastatin 20-40 mg, Pravastatin 40-80 mg, Pitavastatin 1-4 mg |
| Low | <30% | Fluvastatin 20-40 mg, Lovastatin 20 mg |


| Situation | Action |
|---|---|
| Very high-risk ASCVD + LDL-C ≥70 mg/dL | Add ezetimibe or PCSK9 inhibitor (weigh cost) |
| LDL-C ≥190 mg/dL (age 40-75) or FH with LDL-C ≥100 mg/dL | Add ezetimibe, PCSK9 inhibitor, or bile acid sequestrant |
| ACS, already on max statin + LDL-C ≥70 mg/dL | Non-statin agent recommended (Class I) |
| Severity | Action |
|---|---|
| Mild-moderate pain | Stop, wait for resolution, rechallenge with lower dose or different statin |
| Severe pain or weakness | Stop, check CK/creatinine/myoglobin; hospitalize if CK >10x ULN with renal impairment |
| Jaundice or persistent transaminases >5x ULN | Stop, evaluate for other causes |
| New-onset diabetes | Continue statin, encourage lifestyle modification, treat diabetes |
| Situation | Recommendation |
|---|---|
| Age >75 years | Moderate-intensity generally preferred; individualize based on benefit vs. risk |
| Heart failure (ischemic, HFrEF, reasonable life expectancy) | May consider moderate-intensity statin |
| Hemodialysis | Not routinely started; can continue if already initiated |
| Perioperative (non-cardiac surgery) | Continue statins perioperatively if already on them |
| CKD stage 3-4 | Intensive therapy targeting LDL-C <55 mg/dL (2026 Class I) |
Create a statin dosing reference table with all intensities and drug comparisons
| Drug | High Intensity (LDL-C ↓ ≥50%) | Moderate Intensity (LDL-C ↓ 30-49%) | Low Intensity (LDL-C ↓ <30%) |
|---|---|---|---|
| Atorvastatin | 40-80 mg | 10-20 mg | - |
| Rosuvastatin | 20-40 mg | 5-10 mg | - |
| Simvastatin | - | 20-40 mg | 10 mg |
| Pravastatin | - | 40-80 mg | 10-20 mg |
| Lovastatin | - | 40 mg | 20 mg |
| Fluvastatin | - | 80 mg XL or 40 mg BID | 20-40 mg |
| Pitavastatin | - | 2-4 mg | 1 mg |
Note: Only atorvastatin and rosuvastatin achieve high-intensity effect. All other statins cap at moderate intensity.
| Property | Atorvastatin | Rosuvastatin | Simvastatin | Pravastatin | Lovastatin | Fluvastatin | Pitavastatin |
|---|---|---|---|---|---|---|---|
| Max dose | 80 mg | 40 mg | 40 mg* | 80 mg | 80 mg | 80 mg XL | 4 mg |
| Max intensity | High | High | Moderate | Moderate | Moderate | Moderate | Moderate |
| Metabolism | CYP3A4 | Minimal CYP | CYP3A4 | Not CYP | CYP3A4 | CYP2C9 | CYP2C9 (minor) |
| Lipophilicity | Lipophilic | Hydrophilic | Lipophilic | Hydrophilic | Lipophilic | Lipophilic | Lipophilic |
| Renal excretion | <2% | ~10% | <13% | ~20% | ~10% | ~5% | ~15% |
| Half-life | ~14 h | ~19 h | ~3 h | ~2-3 h | ~3 h | ~3 h | ~12 h |
| Dosing | Any time | Any time | Evening | Any time | With evening meal | Any time | Any time |
| CKD-friendly | Yes | Caution (dose limit 10 mg in severe CKD) | Yes | Yes | Yes | Yes | Yes (preferred in CKD) |
| Drug interactions (CYP3A4) | High risk | Low risk | High risk | Low risk | High risk | Low risk | Low risk |
| Crosses BBB | Yes | No | Yes | No | Yes | No | No |
*Simvastatin 80 mg is no longer recommended due to myopathy risk - FDA restricts new initiations at this dose.
| Clinical Situation | Recommended Intensity | Preferred Agents |
|---|---|---|
| Clinical ASCVD (secondary prevention), age ≤75 | High | Atorvastatin 40-80 mg or Rosuvastatin 20-40 mg |
| Clinical ASCVD, age >75 | Moderate (individualize) | Atorvastatin 10-20 mg or Rosuvastatin 5-10 mg |
| ACS (acute coronary syndrome) | High (initiate at admission) | Atorvastatin 80 mg or Rosuvastatin 40 mg |
| LDL-C ≥190 mg/dL (FH) | High | Atorvastatin 40-80 mg or Rosuvastatin 20-40 mg |
| Diabetes + ≥7.5% 10-yr ASCVD risk | High | Atorvastatin 40-80 mg or Rosuvastatin 20-40 mg |
| Diabetes + <7.5% 10-yr ASCVD risk | Moderate | Any moderate-intensity agent |
| Primary prevention, 10-yr risk ≥20% | High | Atorvastatin 40-80 mg or Rosuvastatin 20-40 mg |
| Primary prevention, 10-yr risk 7.5-<20% | Moderate | Any moderate-intensity agent |
| Primary prevention, 10-yr risk 5-<7.5% | Moderate (after discussion) | Any moderate-intensity agent |
| CKD stage 3-4 (2026 guideline, target LDL <55) | High | Atorvastatin 40-80 mg (preferred) |
| On dialysis | Not routinely started | - |
| Drug interaction risk (e.g., calcineurin inhibitors, azole antifungals, HIV PIs) | Moderate with low-interaction statin | Pravastatin, Fluvastatin, or Pitavastatin |
| Heart failure (ischemic, HFrEF, not on statin) | Moderate (may consider) | Rosuvastatin 5-10 mg |
| Risk Category | LDL-C Target |
|---|---|
| Very high-risk ASCVD (multiple events or event + high-risk conditions) | <55 mg/dL |
| High-risk ASCVD / CAC ≥1,000 AU | <55 mg/dL (≥50% reduction from baseline) |
| High 10-yr risk (≥10%) or CAC 100-999 AU | <70 mg/dL |
| Intermediate risk / on statin therapy | <100 mg/dL |
| Borderline risk (3-<5%), if treatment chosen | <100 mg/dL |
| LDL-C ≥190 mg/dL on statin alone | Add non-statin if LDL-C remains >100 mg/dL |
| Situation | Add-on Agent(s) |
|---|---|
| Very high-risk ASCVD + LDL-C ≥70 on max statin | Ezetimibe first, then PCSK9 inhibitor |
| LDL-C ≥190 on max statin, LDL-C still >100 | Ezetimibe, then PCSK9 inhibitor or bile acid sequestrant |
| ACS, on max statin + LDL-C ≥70 mg/dL | Ezetimibe or PCSK9 inhibitor (Class I) |
| FH, homozygous | Lomitapide, mipomersen, LDL apheresis |
| Drug | Dose | Expected LDL-C Reduction |
|---|---|---|
| Atorvastatin | 40 mg daily | ~47-50% |
| Atorvastatin | 80 mg daily | ~55-60% |
| Rosuvastatin | 20 mg daily | ~52-55% |
| Rosuvastatin | 40 mg daily | ~55-63% |
Rosuvastatin is approximately twice as potent per mg as atorvastatin, which is twice as potent as simvastatin. (Goodman & Gilman's)
Create a downloadable PDF reference card of this dosing table
mkdir -p /home/daytona/workspace/statin-reference && ls /home/daytona/workspace/statin-reference
~/statin-reference/generate_pdf.py
from reportlab.lib.pagesizes import A4, landscape
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.platypus import (
SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import Flowable
OUTPUT = "/home/daytona/workspace/statin-reference/Statin_Dosing_Reference_Card.pdf"
# ── Colour palette ─────────────────────────────────────────────────────────────
C_NAVY = colors.HexColor("#1a3a5c")
C_TEAL = colors.HexColor("#1a7a8a")
C_HIGH = colors.HexColor("#c0392b") # high intensity rows
C_HIGH_LT = colors.HexColor("#fdecea")
C_MOD = colors.HexColor("#1a7a8a") # moderate intensity rows
C_MOD_LT = colors.HexColor("#e8f6f8")
C_LOW = colors.HexColor("#7f8c8d") # low intensity rows
C_LOW_LT = colors.HexColor("#f4f4f4")
C_HEADER = colors.HexColor("#1a3a5c")
C_HDR_TEXT = colors.white
C_ALT = colors.HexColor("#f0f4f8")
C_WARN = colors.HexColor("#fff3cd")
C_WARN_BRD = colors.HexColor("#e6a817")
C_BLACK = colors.HexColor("#1a1a1a")
C_GREY = colors.HexColor("#555555")
C_LIGHT_GREY= colors.HexColor("#e0e0e0")
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=12*mm, rightMargin=12*mm,
topMargin=12*mm, bottomMargin=12*mm,
title="Statin Dosing Reference Card",
author="Orris Medical Reference",
subject="Statin therapy guidelines 2026 ACC/AHA"
)
W, H = A4
usable_w = W - 24*mm
styles = getSampleStyleSheet()
# ── Custom paragraph styles ────────────────────────────────────────────────────
def ps(name, parent="Normal", **kwargs):
return ParagraphStyle(name, parent=styles[parent], **kwargs)
title_style = ps("Title2", fontSize=18, textColor=C_HDR_TEXT, alignment=TA_CENTER,
fontName="Helvetica-Bold", spaceAfter=2)
subtitle_style= ps("Sub", fontSize=9, textColor=colors.HexColor("#b0c4de"),
alignment=TA_CENTER, fontName="Helvetica", spaceAfter=0)
section_style = ps("Sect", fontSize=10, textColor=C_HDR_TEXT, fontName="Helvetica-Bold",
alignment=TA_LEFT, spaceBefore=4, spaceAfter=2)
cell_style = ps("Cell", fontSize=7.5, textColor=C_BLACK, fontName="Helvetica",
leading=10)
cell_bold = ps("CellB", fontSize=7.5, textColor=C_BLACK, fontName="Helvetica-Bold",
leading=10)
cell_hdr = ps("CellH", fontSize=7.5, textColor=C_HDR_TEXT, fontName="Helvetica-Bold",
leading=10, alignment=TA_CENTER)
cell_center = ps("CellC", fontSize=7.5, textColor=C_BLACK, fontName="Helvetica",
leading=10, alignment=TA_CENTER)
cell_red = ps("CellR", fontSize=7.5, textColor=C_HIGH, fontName="Helvetica-Bold",
leading=10, alignment=TA_CENTER)
cell_teal = ps("CellT", fontSize=7.5, textColor=C_MOD, fontName="Helvetica-Bold",
leading=10, alignment=TA_CENTER)
cell_grey = ps("CellG", fontSize=7.5, textColor=C_LOW, fontName="Helvetica",
leading=10, alignment=TA_CENTER)
note_style = ps("Note", fontSize=6.5, textColor=C_GREY, fontName="Helvetica-Oblique",
leading=8.5, spaceBefore=1)
source_style = ps("Src", fontSize=6, textColor=C_GREY, fontName="Helvetica",
leading=7.5, spaceBefore=2)
pearl_style = ps("Pearl", fontSize=7, textColor=C_BLACK, fontName="Helvetica",
leading=9.5, spaceBefore=0)
def P(txt, style=cell_style): return Paragraph(txt, style)
def PH(txt): return Paragraph(txt, cell_hdr)
def PC(txt): return Paragraph(txt, cell_center)
def PB(txt): return Paragraph(txt, cell_bold)
# ── Table helper ───────────────────────────────────────────────────────────────
def base_style(has_header=True):
s = [
("GRID", (0,0), (-1,-1), 0.4, C_LIGHT_GREY),
("ROWBACKGROUNDS", (0, 1 if has_header else 0), (-1,-1), [colors.white, C_ALT]),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING",(0,0),(-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING",(0,0), (-1,-1), 4),
]
if has_header:
s += [
("BACKGROUND", (0,0), (-1,0), C_HEADER),
("ROWBACKGROUNDS", (0,0), (-1,0), [C_HEADER]),
]
return s
# ── Section banner ─────────────────────────────────────────────────────────────
def section_banner(text, color=C_NAVY):
data = [[Paragraph(text, section_style)]]
t = Table(data, colWidths=[usable_w])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING",(0,0), (-1,-1), 4),
("ROUNDEDCORNERS", [3]),
]))
return t
# ── Header banner ──────────────────────────────────────────────────────────────
def header_block():
data = [
[Paragraph("STATIN DOSING REFERENCE CARD", title_style)],
[Paragraph("Based on 2026 ACC/AHA/AACVPR Dyslipidemia Guideline | Goldman-Cecil Medicine | Goodman & Gilman's", subtitle_style)],
]
t = Table(data, colWidths=[usable_w])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_NAVY),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING",(0,0),(-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING",(0,0), (-1,-1), 8),
]))
return t
# ── Legend strip ───────────────────────────────────────────────────────────────
def legend_strip():
items = [
(C_HIGH, C_HIGH_LT, "HIGH intensity ≥50% LDL↓"),
(C_MOD, C_MOD_LT, "MODERATE intensity 30-49% LDL↓"),
(C_LOW, C_LOW_LT, "LOW intensity <30% LDL↓"),
]
cells = []
for fg, bg, label in items:
p = Paragraph(f'<font color="#{fg.hexval()[1:]}"><b>{label}</b></font>',
ps("leg", fontSize=7, fontName="Helvetica-Bold", alignment=TA_CENTER, leading=9))
cells.append(p)
t = Table([cells], colWidths=[usable_w/3]*3)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), C_HIGH_LT),
("BACKGROUND", (1,0), (1,0), C_MOD_LT),
("BACKGROUND", (2,0), (2,0), C_LOW_LT),
("BOX", (0,0), (0,0), 0.6, C_HIGH),
("BOX", (1,0), (1,0), 0.6, C_MOD),
("BOX", (2,0), (2,0), 0.6, C_LOW),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
]))
return t
# ═══════════════════════════════════════════════════════════════════════════════
# TABLE 1: Intensity by Drug & Dose
# ═══════════════════════════════════════════════════════════════════════════════
def table1():
cw = [usable_w*0.20, usable_w*0.25, usable_w*0.30, usable_w*0.25]
hdr = [PH("Drug"), PH("High Intensity\n(LDL-C ↓ ≥50%)"), PH("Moderate Intensity\n(LDL-C ↓ 30–49%)"), PH("Low Intensity\n(LDL-C ↓ <30%)")]
rows = [
[PB("Atorvastatin"), Paragraph("<b>40–80 mg</b>", cell_red), PC("10–20 mg"), PC("—")],
[PB("Rosuvastatin"), Paragraph("<b>20–40 mg</b>", cell_red), PC("5–10 mg"), PC("—")],
[PB("Simvastatin"), PC("—"), PC("20–40 mg"), PC("10 mg")],
[PB("Pravastatin"), PC("—"), PC("40–80 mg"), PC("10–20 mg")],
[PB("Lovastatin"), PC("—"), PC("40 mg"), PC("20 mg")],
[PB("Fluvastatin"), PC("—"), PC("80 mg XL\n40 mg BID"), PC("20–40 mg")],
[PB("Pitavastatin"), PC("—"), PC("2–4 mg"), PC("1 mg")],
]
data = [hdr] + rows
t = Table(data, colWidths=cw, repeatRows=1)
style = base_style()
# Colour HIGH intensity cells
style += [
("BACKGROUND", (1,1), (1,2), C_HIGH_LT),
("BACKGROUND", (2,1), (2,7), C_MOD_LT),
("BACKGROUND", (3,1), (3,7), C_LOW_LT),
# dash cells neutral
("TEXTCOLOR", (1,3), (1,7), C_GREY),
]
t.setStyle(TableStyle(style))
return t
# ═══════════════════════════════════════════════════════════════════════════════
# TABLE 2: High-Intensity Quick Reference
# ═══════════════════════════════════════════════════════════════════════════════
def table2():
cw = [usable_w*0.25, usable_w*0.25, usable_w*0.50]
hdr = [PH("Drug"), PH("Dose"), PH("Expected LDL-C Reduction")]
rows = [
[PB("Atorvastatin"), Paragraph("<b>40 mg</b>", cell_red), Paragraph("~47–50%", cell_red)],
[PB("Atorvastatin"), Paragraph("<b>80 mg</b>", cell_red), Paragraph("~55–60% (max dose)", cell_red)],
[PB("Rosuvastatin"), Paragraph("<b>20 mg</b>", cell_red), Paragraph("~52–55%", cell_red)],
[PB("Rosuvastatin"), Paragraph("<b>40 mg</b>", cell_red), Paragraph("~55–63% (max dose)", cell_red)],
]
data = [hdr] + rows
t = Table(data, colWidths=cw, repeatRows=1)
style = base_style()
style += [("BACKGROUND", (0,1), (-1,-1), C_HIGH_LT)]
t.setStyle(TableStyle(style))
return t
# ═══════════════════════════════════════════════════════════════════════════════
# TABLE 3: Drug Comparison
# ═══════════════════════════════════════════════════════════════════════════════
def table3():
props = ["Max dose", "Max intensity", "Metabolism", "Lipophilicity",
"Half-life", "Dosing time", "Drug interactions\n(CYP3A4 risk)", "CKD note"]
drugs = ["Atorva-\nstatin", "Rosuva-\nstatin", "Simva-\nstatin", "Prava-\nstatin",
"Lova-\nstatin", "Fluva-\nstatin", "Pitava-\nstatin"]
values = [
["80 mg", "40 mg", "40 mg*", "80 mg", "80 mg", "80 mg XL", "4 mg"],
["HIGH", "HIGH", "Mod.", "Mod.", "Mod.", "Mod.", "Mod."],
["CYP3A4", "Minimal", "CYP3A4", "Non-CYP", "CYP3A4", "CYP2C9", "CYP2C9\n(minor)"],
["Lipophilic","Hydro-\nphilic","Lipophilic","Hydro-\nphilic","Lipophilic","Lipophilic","Lipophilic"],
["~14 h", "~19 h", "~3 h", "~2-3 h", "~3 h", "~3 h", "~12 h"],
["Any time","Any time","Evening", "Any time","w/ evening\nmeal","Any time","Any time"],
["HIGH", "LOW", "HIGH", "LOW", "HIGH", "LOW", "LOW"],
["OK", "≤10 mg if\neGFR<30", "OK", "OK (preferred)","OK","OK","Preferred\nin CKD"],
]
tiny = ps("Tiny", fontSize=6.5, fontName="Helvetica", leading=8.5, alignment=TA_CENTER)
tiny_b = ps("TinyB", fontSize=6.5, fontName="Helvetica-Bold", leading=8.5, alignment=TA_CENTER)
tiny_hdr = ps("TinyH", fontSize=6.5, fontName="Helvetica-Bold", leading=8.5,
alignment=TA_CENTER, textColor=C_HDR_TEXT)
tiny_prop = ps("TinyP", fontSize=6.5, fontName="Helvetica-Bold", leading=8.5,
alignment=TA_LEFT, textColor=C_HDR_TEXT)
prop_w = usable_w * 0.155
drug_w = (usable_w - prop_w) / 7
hdr_row = [Paragraph("Property", tiny_prop)] + [Paragraph(d, tiny_hdr) for d in drugs]
data = [hdr_row]
for i, prop in enumerate(props):
row = [Paragraph(prop, ps(f"tp{i}", fontSize=6.5, fontName="Helvetica-Bold",
leading=8.5, alignment=TA_LEFT))]
for j, val in enumerate(values[i]):
if val in ("HIGH", "HIGH\n(risk)"):
row.append(Paragraph(val, ps(f"hv{i}{j}", fontSize=6.5, fontName="Helvetica-Bold",
leading=8.5, alignment=TA_CENTER, textColor=C_HIGH)))
elif val in ("Mod.", "LOW"):
clr = C_MOD if val == "Mod." else colors.HexColor("#27ae60")
row.append(Paragraph(val, ps(f"mv{i}{j}", fontSize=6.5, fontName="Helvetica-Bold",
leading=8.5, alignment=TA_CENTER, textColor=clr)))
else:
row.append(Paragraph(val, tiny))
data.append(row)
cw = [prop_w] + [drug_w]*7
t = Table(data, colWidths=cw, repeatRows=1)
style = base_style()
style += [
("BACKGROUND", (0,0), (0,-1), C_TEAL),
("BACKGROUND", (0,0), (-1,0), C_HEADER),
("ROWBACKGROUNDS", (1,1), (-1,-1), [colors.white, C_ALT]),
]
t.setStyle(TableStyle(style))
return t
# ═══════════════════════════════════════════════════════════════════════════════
# TABLE 4: Who Gets What Intensity
# ═══════════════════════════════════════════════════════════════════════════════
def table4():
cw = [usable_w*0.40, usable_w*0.22, usable_w*0.38]
hdr = [PH("Clinical Situation"), PH("Intensity"), PH("Preferred Agent(s)")]
data_rows = [
("Clinical ASCVD, age ≤75 (secondary prevention)", "HIGH",
"Atorvastatin 40–80 mg\nRosuvastatin 20–40 mg"),
("Clinical ASCVD, age >75", "MODERATE",
"Atorvastatin 10–20 mg\nRosuvastatin 5–10 mg"),
("ACS — initiate at admission", "HIGH",
"Atorvastatin 80 mg or Rosuvastatin 40 mg"),
("LDL-C ≥190 mg/dL (familial hypercholesterolaemia)", "HIGH",
"Atorvastatin 40–80 mg\nRosuvastatin 20–40 mg"),
("Diabetes + 10-yr ASCVD risk ≥7.5%", "HIGH",
"Atorvastatin 40–80 mg\nRosuvastatin 20–40 mg"),
("Diabetes + 10-yr ASCVD risk <7.5%", "MODERATE",
"Any moderate-intensity agent"),
("Primary prevention, 10-yr risk ≥20%", "HIGH",
"Atorvastatin 40–80 mg\nRosuvastatin 20–40 mg"),
("Primary prevention, 10-yr risk 7.5–<20%", "MODERATE",
"Any moderate-intensity agent"),
("Primary prevention, 10-yr risk 5–<7.5%", "MODERATE\n(after discussion)",
"Any moderate-intensity agent"),
("CKD stage 3–4 (target LDL <55 mg/dL)", "HIGH",
"Atorvastatin 40–80 mg (preferred)"),
("High drug-interaction risk (calcineurin inhibitors, azoles, HIV PIs)", "MODERATE",
"Pravastatin or Pitavastatin"),
("Ischaemic HFrEF, not already on statin", "MODERATE (consider)",
"Rosuvastatin 5–10 mg"),
("Dialysis", "NOT routinely started",
"Continue if previously initiated"),
]
rows = [hdr]
for sit, inten, agent in data_rows:
if "HIGH" in inten and "NOT" not in inten:
ip = Paragraph(f'<b>{inten}</b>', ps("iph", fontSize=7.5, fontName="Helvetica-Bold",
alignment=TA_CENTER, textColor=C_HIGH, leading=10))
bg = C_HIGH_LT
elif "MODERATE" in inten:
ip = Paragraph(f'<b>{inten}</b>', ps("ipm", fontSize=7.5, fontName="Helvetica-Bold",
alignment=TA_CENTER, textColor=C_MOD, leading=10))
bg = C_MOD_LT
else:
ip = Paragraph(inten, ps("ipn", fontSize=7.5, fontName="Helvetica",
alignment=TA_CENTER, textColor=C_LOW, leading=10))
bg = C_LOW_LT
rows.append([P(sit), ip, P(agent)])
t = Table(rows, colWidths=cw, repeatRows=1)
style = base_style()
# Colour intensity column cells per row
for i, (_, inten, _) in enumerate(data_rows, start=1):
if "HIGH" in inten and "NOT" not in inten:
style.append(("BACKGROUND", (1, i), (1, i), C_HIGH_LT))
elif "MODERATE" in inten:
style.append(("BACKGROUND", (1, i), (1, i), C_MOD_LT))
else:
style.append(("BACKGROUND", (1, i), (1, i), C_LOW_LT))
t.setStyle(TableStyle(style))
return t
# ═══════════════════════════════════════════════════════════════════════════════
# TABLE 5: LDL-C Targets (2026 Guideline)
# ═══════════════════════════════════════════════════════════════════════════════
def table5():
cw = [usable_w*0.55, usable_w*0.45]
hdr = [PH("Risk Category"), PH("LDL-C Target")]
rows_data = [
("Very high-risk ASCVD (multiple events or 1 event + high-risk conditions)", "<b><font color='#c0392b'><55 mg/dL</font></b>"),
("High-risk ASCVD / CAC ≥1,000 AU", "<b><font color='#c0392b'><55 mg/dL</font></b> (or ≥50% reduction)"),
("High 10-yr risk (≥10%) or CAC 100–999 AU", "<b><font color='#e67e22'><70 mg/dL</font></b>"),
("Primary prevention, high risk (10-yr ≥10%)", "<b><font color='#e67e22'><70 mg/dL</font></b> (Class IIa)"),
("Intermediate risk / on statin therapy", "<b><font color='#1a7a8a'><100 mg/dL</font></b>"),
("Borderline risk (3–<5%), if treatment chosen", "<b><font color='#1a7a8a'><100 mg/dL</font></b>"),
("LDL-C ≥190 on statin alone (LDL-C still >100)", "Add non-statin therapy"),
]
data = [hdr] + [[P(r), Paragraph(t, cell_center)] for r, t in rows_data]
t = Table(data, colWidths=cw, repeatRows=1)
t.setStyle(TableStyle(base_style()))
return t
# ═══════════════════════════════════════════════════════════════════════════════
# TABLE 6: Non-statin Add-on
# ═══════════════════════════════════════════════════════════════════════════════
def table6():
cw = [usable_w*0.52, usable_w*0.48]
hdr = [PH("Situation (on maximally tolerated statin)"), PH("Add-on Agent")]
rows_data = [
("Very high-risk ASCVD + LDL-C ≥70 mg/dL", "Ezetimibe first → then PCSK9 inhibitor"),
("LDL-C ≥190 mg/dL, LDL-C still >100 on statin", "Ezetimibe → PCSK9 inhibitor or bile acid sequestrant"),
("ACS + LDL-C ≥70 mg/dL (Class I)", "Ezetimibe or PCSK9 inhibitor"),
("Familial hypercholesterolaemia (homozygous)", "Lomitapide, mipomersen, or LDL apheresis"),
]
data = [hdr] + [[P(r), P(a)] for r, a in rows_data]
t = Table(data, colWidths=cw, repeatRows=1)
t.setStyle(TableStyle(base_style()))
return t
# ═══════════════════════════════════════════════════════════════════════════════
# TABLE 7: Muscle Symptom Management
# ═══════════════════════════════════════════════════════════════════════════════
def table7():
cw = [usable_w*0.25, usable_w*0.75]
hdr = [PH("Presentation"), PH("Management Steps")]
rows_data = [
("Mild–moderate muscle pain",
"1. Stop statin 2. Wait for resolution 3. Rechallenge with lower dose or different statin 4. Uptitrate as tolerated"),
("Severe pain or weakness",
"1. Stop statin 2. Check CK, creatinine/GFR, urine myoglobin 3. Admit + hydrate if CK >10× ULN with renal impairment 4. Evaluate predisposing factors 5. Refer to lipidologist before restarting"),
("Jaundice or AST/ALT >5× ULN",
"1. Stop statin 2. Evaluate for other hepatitis causes 3. Reinitiate once resolved"),
("New-onset diabetes",
"Continue statin. Encourage lifestyle modification. Treat diabetes."),
]
data = [hdr] + [[P(r), P(a)] for r, a in rows_data]
t = Table(data, colWidths=cw, repeatRows=1)
t.setStyle(TableStyle(base_style()))
return t
# ═══════════════════════════════════════════════════════════════════════════════
# Clinical Pearls box
# ═══════════════════════════════════════════════════════════════════════════════
def pearls_box():
pearls = [
("⚠", "CONTRAINDICATED in pregnancy and lactation (Category X). Counsel all women of childbearing potential."),
("⚠", "Simvastatin 80 mg is no longer recommended (FDA restriction — myopathy risk). Max 40 mg; consider switching."),
("ℹ", "Diabetes risk: statins accelerate diabetes onset by ~2 months in predisposed patients. ASCVD benefit far outweighs this risk (CTT meta-analysis, Lancet Diabetes Endocrinol 2024)."),
("ℹ", "CYP3A4 inhibitors (azole antifungals, macrolides, HIV protease inhibitors) increase levels of atorvastatin, simvastatin, lovastatin — use pravastatin or pitavastatin instead."),
("ℹ", "Rosuvastatin dose ≤10 mg in severe CKD (eGFR <30) or patients on cyclosporine."),
("ℹ", "Pitavastatin and pravastatin are preferred in transplant patients (minimal calcineurin inhibitor interaction)."),
("ℹ", ">90% of reported muscle symptoms in statin users are not caused by the statin (nocebo effect significant)."),
("ℹ", "Liver monitoring: routine ongoing AST/ALT not needed if baseline <2× ULN. Statins do NOT cause hepatotoxicity."),
]
cells = []
for icon, text in pearls:
clr = "#c0392b" if icon == "⚠" else "#1a3a5c"
cells.append(Paragraph(
f'<font color="{clr}"><b>{icon}</b></font> {text}',
ps("pearlx", fontSize=7, fontName="Helvetica", leading=9.5, spaceBefore=0)
))
# 2-column layout
mid = (len(cells) + 1) // 2
left_col = cells[:mid]
right_col = cells[mid:]
# pad to equal length
while len(right_col) < len(left_col):
right_col.append(Paragraph("", pearl_style))
rows = [[l, r] for l, r in zip(left_col, right_col)]
col_w = (usable_w - 4*mm) / 2
t = Table(rows, colWidths=[col_w, col_w])
t.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING",(0,0),(-1,-1), 2),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING",(0,0), (-1,-1), 4),
("LINEAFTER", (0,0), (0,-1), 0.4, C_LIGHT_GREY),
]))
# Outer box
outer = Table([[t]], colWidths=[usable_w])
outer.setStyle(TableStyle([
("BOX", (0,0), (-1,-1), 0.8, C_WARN_BRD),
("BACKGROUND", (0,0), (-1,-1), C_WARN),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING",(0,0), (-1,-1), 4),
]))
return outer
# ═══════════════════════════════════════════════════════════════════════════════
# Build story
# ═══════════════════════════════════════════════════════════════════════════════
SP = lambda n=3: Spacer(1, n*mm)
story = []
# ── Page 1 ─────────────────────────────────────────────────────────────────────
story.append(header_block())
story.append(SP(2))
story.append(legend_strip())
story.append(SP(3))
story.append(section_banner("TABLE 1 — Statin Intensity by Drug & Dose"))
story.append(SP(1))
story.append(table1())
story.append(SP(1))
story.append(Paragraph("* Simvastatin 80 mg no longer recommended (FDA restriction). † Doses in parentheses have moderate evidence for that intensity tier.",
note_style))
story.append(SP(3))
story.append(section_banner("TABLE 2 — High-Intensity Statin Quick Reference"))
story.append(SP(1))
story.append(table2())
story.append(SP(1))
story.append(Paragraph("Rosuvastatin is ~2× more potent per mg than atorvastatin, which is ~2× more potent than simvastatin.",
note_style))
story.append(SP(3))
story.append(section_banner("TABLE 3 — Drug Pharmacology Comparison"))
story.append(SP(1))
story.append(table3())
story.append(SP(1))
story.append(Paragraph("BBB = blood-brain barrier; CKD = chronic kidney disease; CYP = cytochrome P450.",
note_style))
# ── Page 2 ─────────────────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(header_block())
story.append(SP(3))
story.append(section_banner("TABLE 4 — Statin Intensity by Clinical Indication"))
story.append(SP(1))
story.append(table4())
story.append(SP(3))
story.append(section_banner("TABLE 5 — LDL-C Treatment Targets (2026 ACC/AHA Guideline)"))
story.append(SP(1))
story.append(table5())
story.append(SP(1))
story.append(Paragraph("CAC = coronary artery calcium; ASCVD = atherosclerotic cardiovascular disease. Class I = strong recommendation.",
note_style))
story.append(SP(3))
story.append(section_banner("TABLE 6 — When to Add Non-Statin Therapy"))
story.append(SP(1))
story.append(table6())
story.append(SP(3))
story.append(section_banner("TABLE 7 — Managing Adverse Effects During Statin Therapy"))
story.append(SP(1))
story.append(table7())
story.append(SP(3))
story.append(section_banner("CLINICAL PEARLS & SAFETY NOTES", color=colors.HexColor("#7d6608")))
story.append(SP(1))
story.append(pearls_box())
story.append(SP(3))
story.append(HRFlowable(width=usable_w, thickness=0.4, color=C_LIGHT_GREY))
story.append(SP(1))
story.append(Paragraph(
"Sources: Goldman-Cecil Medicine International Edition (Ch. 190) · Goodman & Gilman's Pharmacological Basis of Therapeutics (Ch. 37) · "
"Washington Manual of Medical Therapeutics (Table 3-10) · Henry's Clinical Diagnosis & Management by Laboratory Methods (Table 18.9) · "
"2026 ACC/AHA/AACVPR Dyslipidemia Guideline (Blumenthal et al., JACC/Circulation 2026, PMID 41824590) · "
"CTT Collaboration, Lancet Diabetes Endocrinol 2024 (PMID 38554713) · Banach et al., Mayo Clin Proc 2025 (PMID 40126455)",
source_style
))
doc.build(story)
print("PDF generated:", OUTPUT)
Guidelines for using antiplatelet drugs in pad case