Install
$ agentstack add skill-ranacm-marpsmith-deck-a11y-audit ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Deck a11y audit
Audit a Marp deck and/or its theme CSS for accessibility issues. Output is a markdown report; the user decides what to fix.
Related skills
Part of the marpsmith bundle — composes with:
- marp-slides — builds the decks and themes this audits.
- theme-generator — generate a theme, then audit it here before shipping.
> Script paths below use `` — the skills directory configured by the active agent harness; the marpsmith skills live there together.
Scope
This skill checks:
- WCAG 2.1 contrast —
(L1+0.05)/(L2+0.05)on sRGB relative luminance. AA/AAA pass/fail per pair. - APCA Lc — WCAG 3 draft, perception-tuned. Catches dark-mode cases where WCAG 2 passes a thin-stroke cyan-on-dark pair that looks washed-out at body size.
- Color-blind safety — RGB→RGB Brettel/Viénot matrices for the three dichromacy types; flags pairs that look fine to trichromats but collapse for ~5% of viewers.
- Text size at presentation distance — body text in pt-equivalent vs. expected venue size; flags decks that will fail at >20ft viewing.
- Heading hierarchy —
h1 → h2 → h3order in slide markdown; flags skipped levels. - Reliance on color alone — comparison/matrix/process-flow slides where the only differentiator is hue (e.g., cyan column vs. pink column with identical iconography).
- Motion / animation — Marp itself doesn't animate much, but flag any inline `
with@keyframesor transitions that should respectprefers-reduced-motion`.
This skill defers to:
marp-slides/scripts/check-slides.mjsfor geometric overflow.deck-reviewfor editorial issues (tone, citations, terminology).deck-visual-reviewfor eye-flow / aesthetic judgments.
If the user asks for "everything," recommend running all four in sequence.
Workflow
- Identify inputs. You need either a theme CSS path, a Marp deck markdown path (theme inferred from frontmatter), or both. If neither, ask.
- Run the theme contrast script.
scripts/audit-theme.mjs --md >. This handles checks 1–3 mechanically. It's fast (` blocks sometimes do. - Compose the final report. Merge the script's markdown output with the manual findings into one structured report. Use the template in "Report structure" below.
Do not edit the deck or theme. The report is the deliverable.
Thresholds and rubric
WCAG 2.1 contrast (the well-established standard)
Formula: (Llight + 0.05) / (Ldark + 0.05) where L = 0.2126 R' + 0.7152 G' + 0.0722 B' after sRGB linearization (c/12.92 if c ≤ 0.03928, else ((c+0.055)/1.055)^2.4).
| Text size | AA | AAA | |----------------------------------------|-----|-----| | Normal (10m) | 32pt+ | 48pt+ |
Marp default body is 28px ≈ 21pt. That's auditorium-borderline; safe for conference rooms and explicit auditoriums where the projector is large. A theme that drops to 24px or applies b-90 autoshrink (~25.2px ≈ 19pt) is conference-room only — flag it if the user intends a larger room.
When the deck has explicit b-95 / b-90 autoshrink classes, note those slides specifically: shrinking is the marp-slides skill's last-resort overflow fix and degrades legibility at distance.
Heading hierarchy
Walk the deck slide-by-slide. For each slide, list the heading levels in order. Flag:
- A slide that opens with
##or###and has no preceding#ancestor in the deck (or in the title-cover). - A jump from
h1straight toh3(skippingh2). - A
section-dividerthat usesh3while normal content slides useh1(inverted).
For Marp specifically: title-cover slides use h1, section-divider slides use h2, content slides use h1 (most themes) or h2. Pick one convention and flag deviations. The marp-slides skill's default is content h1.
Reliance on color alone
For each comparison/matrix/contrast slide:
- ✅ OK if both columns have labels in the heading or first line ("✓ Pros" / "✗ Cons", "Before" / "After", "Option A: Buy" / "Option B: Build").
- ✅ OK if both columns use distinguishing icons in the bullet markers.
- ❌ FAIL if the only signal is the column color (e.g., theme paints left column cyan and right column pink, but the user wrote
Pros\n- foo\n- barandCons\n- baz\n- quxwith no other cue and relies on column position alone).
Column position alone is borderline — works for the audience but only if the convention is established earlier. If the deck uses 2-column comparisons in 4+ slides and they all follow the same left=positive/right=negative convention, that's an established convention and OK. If it's inconsistent, flag it.
Report structure
# Deck a11y audit —
**Source:** /path/to/deck.md or /path/to/theme.css
**Audited:** YYYY-MM-DD
**Pairs audited:** N (script) + M (manual)
## Summary
- HIGH failures: N
- MED failures: N
- LOW failures: N
- CVD-collapsed pairs: N
- Heading-hierarchy issues: N slides
- Color-only-signal slides: N
- Presentation-distance concerns: N slides
## Contrast findings (from audit-theme.mjs)
## Heading hierarchy
## Color-only signal
## Presentation distance
## Motion
## Recommended next actions
1. **Replace link color #008787 with #2EB8B8** — passes AA at 4.6:1 (5 min).
2. **Add explicit ✓/✗ icons to compare-grid bullets in slides 6, 11, 14** — removes hue dependency for CVD viewers (15 min).
3. **Raise heading h2 on slide 4 to h1** — fixes hierarchy (1 min).
What NOT to do
- Don't edit the deck or theme. Output recommendations. Theme palette changes ripple across every deck using that theme — the user owns that call.
- Don't conflate "passes WCAG 2" with "looks good in dark mode". APCA exists because WCAG 2 over-credits saturated colors against dark backgrounds. Report both.
- Don't flag every CVD warning as HIGH. A pure-decoration CVD-collapsed accent (e.g., the underline beneath a heading) is LOW. A CVD-collapsed signal-bearing color (the comparison column accent) is HIGH.
- Don't recommend specific exotic colors as fixes. Suggest a target lightness and tell the user to pick the nearest palette color. The script's
Suggested fix:field gives a neutral-axis target; that's a floor, not a recommendation to actually use neutral gray. - Don't audit themes you don't have the path to. Marp's
theme:frontmatter directive can resolve to a global theme registered via.marprc.yml. If you can't read the CSS, say so and audit only the deck-level concerns (hierarchy, color-only signals). - Don't extrapolate from CSS to render. The script reads colors from CSS but doesn't render. If a theme uses
text-shadow: 0 0 8px currentColor(synthwave does), the rendered contrast is higher than CSS-pair contrast. Note this caveat for any glow-effect theme.
Pitfalls
- rgba() alpha-blending. The script alpha-composites foreground tints over the slide background. But it does not composite over a card tint background — e.g.,
--card-tint: rgba(255,255,255,0.04)inside acomparisoncell. For cards, manually do the composite and re-audit if a finding is borderline. (Concretely: acomparisonbody text pair isbody-colorovercard-tint blended over slide-bg, notbody-color over slide-bg.) - CSS imports. Themes
@import 'default';from Marp's default theme. Anything not overridden in the theme file falls back to Marp default (black text on white). The script doesn't follow imports — it reports what's explicitly defined. If a key pair is missing from the script output, the theme inherits Marp default for that selector; treat it as a separate finding. color: inheritandcurrentColor. The script treats these as unparseable and skips. That's intentional — they don't have a fixed contrast pair until resolved against an ancestor.- Heading hierarchy in Marp. Slide separators (
---) reset visual hierarchy but not the markdown's#semantics. A deck with 30 slides each starting with#produces 30h1s — that's normal for Marp and not a hierarchy violation. - CVD matrices are approximations. Brettel/Viénot is a widely-used dichromacy model; real-world CVD is anomalous trichromacy (partial cone loss) in most cases. The simulation is conservative — if it passes, real users very likely pass; if it fails, real users might still be OK. Don't promise 100% safety.
- APCA is in draft. WCAG 3 is not finalized. Treat APCA as advisory until W3C lands the spec. The Lc thresholds here match the v0.0.98G-4g constants used by
apca-w3on npm.
Quality checklist
Before declaring done:
- Script ran without errors and reported a non-empty pair list. If the script returned an empty list, the theme is non-Marp or uses a CSS structure the extractor doesn't understand — fall back to a manual color audit instead.
- Report covers all seven scope items (contrast, APCA, CVD, distance, hierarchy, color-only, motion). Even if a section is "no concerns," explicitly state it.
- HIGH findings have a concrete suggested fix with a target color or specific markdown change.
- CVD findings distinguish text-readability from signal-encoding. A cyan heading that's CVD-collapsed for trichromacy-vs-deuteranopia is fine (it's still high-contrast in luminance), but a cyan-vs-pink comparison column is a signal-encoding failure.
- Presentation-distance recommendation is venue-tagged. "OK for conference rooms; borderline for auditoriums" beats "body text might be small."
Script usage
# Text summary (quick scan):
node /deck-a11y-audit/scripts/audit-theme.mjs
# Markdown report (for merging into the final audit):
node /deck-a11y-audit/scripts/audit-theme.mjs --md
The script has no external dependencies — pure Node. It implements WCAG, APCA, and CVD inline (no apca-w3 / chroma-js needed). If you find yourself wanting hsl()/lab()/named-color support beyond the tiny built-in set, swap in culori — but that's a future-pass improvement, not a current need for Marp themes (which use hex everywhere).
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: RanaCM
- Source: RanaCM/marpsmith
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.