Check burned-in caption contrast against WCAG 1.4.3 before rendering
WCAG 1.4.3 asks for 4.5:1 contrast on normal text and 3:1 on large text. Compute the ratio in Python, then set design.colors on a Sume caption job.

W3C's Understanding page for success criterion 1.4.3 sets the minimum at 4.5:1 for normal text and 3:1 for large text, and says images of text are covered. A burned-in caption is drawn text, so a quick ratio check on your caption colours before you pay for a render is cheap insurance.
The thresholds
The page states the figures below. Treat them as the bar for the fill colour against whatever sits behind it.
| Text | Minimum ratio |
|---|---|
| Normal text | 4.5:1 |
| Large text | 3:1 |
A ratio function you can run
This uses the relative luminance formula from WCAG. Pass the caption fill and the colour behind it; if the background is a card, use the card colour.
def lum(hex_color):
rgb = [int(hex_color[i:i + 2], 16) / 255 for i in (1, 3, 5)]
lin = [c / 12.92 if c <= 0.03928 else ((c + 0.055) / 1.055) ** 2.4 for c in rgb]
return 0.2126 * lin[0] + 0.7152 * lin[1] + 0.0722 * lin[2]
def ratio(a, b):
hi, lo = sorted((lum(a), lum(b)), reverse=True)
return (hi + 0.05) / (lo + 0.05)
for fg, bg in [("#FFFFFF", "#000000"), ("#22D3EE", "#FFFFFF"), ("#FFE600", "#1A1A1A")]:
r = ratio(fg, bg)
print(fg, bg, round(r, 2), "ok" if r >= 4.5 else "fails 4.5:1")Applying it to a Sume caption job
design.colors takes base, active, stroke, accent, accent_deep and card, as hex, rgb(), rgba() or transparent. Out-of-range values are a 400 at request time, so a bad look fails before it bills. design is not supported on punch or tiktok-green.
A white base on a dark card clears the bar easily. A bright active-word colour such as cyan against a white background does not, so check the active colour against the card, not just the base.
What this does not cover
Contrast against moving video behind the text varies frame to frame, which is why a solid card or a heavy stroke is safer than a bare fill. Run the check on the colours you control and review a rendered frame for the rest.
Sources
Related posts
More in Use cases
- Picture book illustrations: 12 spreads x 3 takes cost $2.64
Twelve spreads at three takes each on ChatGPT Image 2.5 cost $2.3715, and a four-take cover adds $0.2635, so $2.635 before reference-image tokens on Sume.
- Tree lot care cards: 1 quart of water per inch of stem, as clips
The National Christmas Tree Association says a stand needs 1 quart per inch of stem diameter. Turn its care rules into three captioned clips for about $0.66.
- Chrome heavy ad intervention for VAST video: 4 MB and 60 s limits
Microsoft's VAST guidance warns Chrome can block video ad iframes over 4 MB, 60 s of main thread or 15 s in 30 s. What a finished Sume MP4 changes.
- Christmas Eve service times video for a congregation, from photos
Christmas Day is Dec 25, 2026. Make a 15-second vertical notice of service times from real photos of your building, with caption cues you type yourself.
Written by Sume