From design
Audit designs and code for WCAG 2.1 AA compliance. Trigger with "is this accessible", "accessibility check", "WCAG audit", "can screen readers use this", "color contrast", or when the user asks about making designs or code accessible to all users.
npx claudepluginhub hanniyausmani/xd-skills --plugin designThis skill uses the workspace's default tool permissions.
Evaluate designs and implementations against WCAG 2.1 AA standards.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
Evaluate designs and implementations against WCAG 2.1 AA standards.
When a Figma URL or node is provided, always output the accessibility review directly onto the Figma canvas using mcp__c559ff4b-9d7d-4192-8308-d9036a7e621f__use_figma. Do NOT output as text in the conversation — place it in Figma instead. Only fall back to text output if no Figma file is available.
rgb(255,255,255)) — never dark backgrounds; text becomes invisible on darklayoutMode = "VERTICAL" auto-layout. Auto-layout frames collapse to height 10 in the Plugin API and are unreliablet.textAutoResize = "HEIGHT" BEFORE calling t.resize(fixedWidth, t.height). If you call resize(w, 999) first, the node gets stuck at height 999panel.resize(PW, cy + PAD) to set the final heightfigma.viewport.scrollAndZoomIntoView([targetNode, panel]) so both are visiblecy Y-cursor)bg: rgb(255,255,255) // panel background — always white
surf: rgb(246,246,251) // card/item surface
line: rgb(218,218,236) // dividers
h1: rgb(12,12,30) // primary headings
h2: rgb(35,35,65) // item labels
body: rgb(70,70,105) // body text
muted: rgb(135,135,175) // subtitles, metadata
red: rgb(188,35,35) // fail / high priority / header accent
amb: rgb(158,108,0) // needs attention / medium priority
grn: rgb(22,150,70) // pass / low priority
pur: rgb(100,50,230) // recommendations section accent
rgb_: rgb(254,222,222) // red pill background
agb: rgb(255,242,195) // amber pill background
ggb: rgb(213,250,226) // green pill background
pgb: rgb(237,228,255) // purple pill background
The order of operations matters. Set textAutoResize before resize():
function mkT(str, size, style, color, fixW) {
const t = figma.createText();
t.fontName = { family: "Inter", style };
t.fontSize = size;
t.fills = [{ type: "SOLID", color }];
t.characters = str;
if (fixW) {
t.textAutoResize = "HEIGHT"; // MUST come before resize()
t.resize(fixW, t.height); // sets width; height auto-calculates correctly
}
return t; // t.height is now the real rendered height — safe to use in layout math
}
Calculate card height from real text heights, then create the frame at that exact size. Never rely on auto-layout:
const pill = mkPill(tagLabel, tagTc, tagBg); // always 20px tall
const lbl = mkT(criterion, 13, "Semi Bold", C.h2, IW - 32);
const bod = mkT(finding, 12, "Regular", C.body, IW - 32);
const iH = 12 + pill.height + 6 + lbl.height + 5 + bod.height + 12;
const card = figma.createFrame();
card.resize(IW, iH);
card.fills = [{ type: "SOLID", color: C.surf }];
card.cornerRadius = 8;
card.clipsContent = false;
pill.x = 16; pill.y = 12;
lbl.x = 16; lbl.y = 12 + pill.height + 6;
bod.x = 16; bod.y = 12 + pill.height + 6 + lbl.height + 5;
card.appendChild(pill); card.appendChild(lbl); card.appendChild(bod);
card.x = PAD; card.y = cy;
panel.appendChild(card);
cy += iH + 8;
// Before building — remove any old panel
figma.currentPage.children.forEach(n => {
if (n.name === "♿ Accessibility Review") n.remove();
});
// After building — size panel and zoom to show both
panel.resize(PW, cy + PAD);
panel.x = targetNode.x + targetNode.width + 80;
panel.y = targetNode.y;
figma.currentPage.appendChild(panel);
figma.viewport.scrollAndZoomIntoView([targetNode, panel]);
Always load these before creating any text nodes:
await figma.loadFontAsync({ family: "Inter", style: "Bold" });
await figma.loadFontAsync({ family: "Inter", style: "Semi Bold" });
await figma.loadFontAsync({ family: "Inter", style: "Regular" });