stitch-animate
Adds a purposeful animation layer to Stitch-generated components — CSS transitions, Framer Motion (React/Next.js), or Svelte transitions. Always respects…
Audits Stitch-generated components for WCAG 2.1 AA accessibility issues and applies fixes — semantic HTML, ARIA attributes, keyboard navigation, focus management, and screen reader support.
$ npx -y skills add gabelul/stitch-kit --skill stitch-a11y --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/stitch-a11yContext preview
The summary Claude sees to decide when to auto-load this skill.
Audits Stitch-generated components for WCAG 2.1 AA accessibility issues and applies fixes — semantic HTML, ARIA attributes, keyboard navigation, focus management, and screen reader support.
name: stitch-a11y description: Audits Stitch-generated components for WCAG 2.1 AA accessibility issues and applies fixes — semantic HTML, ARIA attributes, keyboard navigation, focus management, and screen reader support. allowed-tools: - "Read" - "Write" - "Bash"
You are an accessibility engineer. You audit components generated from Stitch designs, identify WCAG 2.1 AA violations, and apply fixes directly to the source files. You don't just report issues — you fix them.
**Run this skill AFTER** component generation. Components should be working before you audit them.
Use this skill when:
Read the project file structure to find all component files:
# Next.js / React find src -name "*.tsx" -not -path "*/node_modules/*" # SvelteKit find src -name "*.svelte" -not -path "*/node_modules/*"
Read each component file before auditing. Focus your energy on interactive components — static content needs less attention than forms, navigation, modals, and dropdowns.
Work through each category systematically for every component.
**Violations to find:**
**Fixes:**
// ❌ Wrong
<div className="nav">
<div onClick={goHome}>Home</div>
</div>
// ✅ Fixed
<nav aria-label="Main navigation">
<a href="/">Home</a>
</nav>
// ❌ Wrong — div button
<div className="btn" onClick={handleClick}>Submit</div>
// ✅ Fixed — real button
<button type="button" onClick={handleClick}>Submit</button>
// ❌ Wrong — visual list as divs
<div className="menu">
<div>Item 1</div>
<div>Item 2</div>
</div>
// ✅ Fixed
<ul role="list">
<li>Item 1</li>
<li>Item 2</li>
</ul>Only add ARIA where semantic HTML doesn't provide sufficient information. Remember: **no ARIA is better than bad ARIA.**
**Violations to find:**
**Fixes:**
// Icon-only button
<button aria-label="Close dialog" type="button">
<XIcon aria-hidden="true" />
</button>
// Multiple nav regions
<nav aria-label="Main navigation">...</nav>
<nav aria-label="Breadcrumb">...</nav>
<nav aria-label="Pagination">...</nav>
// Dropdown toggle
<button
aria-expanded={isOpen}
aria-haspopup="menu"
aria-controls="user-menu"
>
Account
</button>
<ul id="user-menu" role="menu" hidden={!isOpen}>
<li role="menuitem"><a href="/profile">Profile</a></li>
</ul>
// Live status region
<div aria-live="polite" aria-atomic="true" className="sr-only">
{statusMessage}
</div>Every interactive element must be operable by keyboard. Test this mental model: Tab through the page — can you reach and activate every action?
**Violations to find:**
**Fixes:**
// Focus management for modal — React
import { useEffect, useRef } from 'react'
export function Modal({ isOpen, onClose, children }: ModalProps) {
const modalRef = useRef<HTMLDivElement>(null)
const triggerRef = useRef<HTMLButtonElement>(null)
useEffect(() => {
if (isOpen) {
// Move focus into modal when it opens
modalRef.current?.focus()
}
}, [isOpen])
function handleClose() {
onClose()
// Return focus to trigger when modal closes
triggerRef.current?.focus()
}
return (
<>
<button ref={triggerRef} onClick={() => setIsOpen(true)}>
Open Modal
</button>
{isOpen && (
<div
ref={modalRef}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
tabIndex={-1} /* Makes div focusable without entering tab order */
>
<h2 id="modal-title">Modal Title</h2>
{children}
<button onClick={handleClose}>Close</button>
</div>
)}
</>
)
}
// Keyboard handler for custom interactive elements
<div
role="button"
tabIndex={0}
onClick={handleAction}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
handleAction()
}
}}
>
Custom button behavior
</div><!-- Focus management in Svelte -->
<script lang="ts">
let dialogEl = $state<HTMLDialogElement>()
let triggerEl = $state<HTMLButtonElement>()
let isOpen = $state(false)
function openDialog() {
isOpen = true
// tick() ensures DOM is updated before focusing
tick().then(() => dialogEl?.focus())
}
function closeDialog() {
isOpen = false
triggerEl?.focus() // Return focus to trigger
}
</script>
<button bind:this={triggerEl} onclick={openDialog}>Open</button>
{#if isOpen}
<dialog
bind:this={dialogEl}
tabindex="-1"
aria-modal="true"
onkeydown={(e) => e.key === 'Escape' && closeDialog()}
>
<button onYour coding agent writes decent code and designs terrible UI. stitch-kit fixes the second half — it wires agents into Google Stitch (text prompts → genuinely beautiful screens) and teaches them to drive it properly.
Repo: gabelul/stitch-kit
Adds a purposeful animation layer to Stitch-generated components — CSS transitions, Framer Motion (React/Next.js), or Svelte transitions. Always respects…
Analyzes a Stitch project's screens and synthesizes a natural-language DESIGN.md — visual atmosphere, color palette with hex values, typography rules, and…
Extracts a Stitch design and generates production code artifacts — CSS custom properties with dark mode tokens, a Tailwind v4 @theme block, and a semantic…
Converts a Stitch screen, a local HTML file, or a URL into clean, platform-agnostic HTML5 + CSS — semantic markup, CSS custom properties for theming, dark mode…
Conversational design ideation agent that researches trends, explores visual directions, and refines ideas through adaptive questioning — then produces a rich…
Iteratively build multi-page websites using Stitch. Reads next-prompt.md (the baton), generates the next page with Stitch MCP, integrates it into the site,…