SUPER-DESIGN.md
SaferSkills independently audited SUPER-DESIGN (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You enforce a production design system. Read DESIGN.md before editing UI. Emit tokens, never literals. Ship full state coverage. Build every component reusable. Validate with the bundled scripts.
Any UI code you write references DESIGN.md tokens by name. No #hex, no rgb()/hsl(), no raw px outside the scale, no inline style={{ color: ... }}. Every interactive element defines hover, focus-visible, active, disabled — buttons add loading, inputs add error and readonly. Focus rings use :focus-visible with a double-layer box-shadow for 3:1 contrast at all offsets. Motion is transform and opacity only, under 300ms, guarded by prefers-reduced-motion. Files stay under 300 LOC, functions under 80 LOC, JSX depth under 6, hooks per component under 10. Every component declares an exported `Props` interface. Every interactive element has `min-h-11 min-w-11` (44×44 touch target). Every layout has responsive breakpoints or container queries. Layouts pass at 320/375/768/1024/1440/1920. Run bash scripts/test.sh <file> before declaring done — target score ≥ 90.
❌ Rejected by the hook:
<button
style={{ background: '#5e6ad2', padding: '17px' }}
className="rounded-[6px] hover:bg-[#828fff]"
onClick={submit}
>
Save
</button>Rejected for: literal hex (×2), off-scale px, arbitrary Tailwind value, no :focus-visible, no :disabled, no :active, no min size, no type, no aria-busy on async click.
✓ Accepted:
<Button variant="primary" size="md" loading={isPending} onClick={submit}>
Save
</Button>With a Button that reads:
// components/ui/button.tsx — 92 LOC
const buttonVariants = cva(
[
"inline-flex items-center justify-center gap-2 whitespace-nowrap",
"rounded-md font-medium select-none",
"transition-[background-color,box-shadow,transform] duration-fast ease-out",
"focus-visible:outline-none",
"focus-visible:shadow-[0_0_0_2px_var(--color-bg),0_0_0_5px_var(--color-focus-ring)]",
"active:scale-[0.98]",
"disabled:opacity-50 disabled:pointer-events-none",
"aria-busy:opacity-70 aria-busy:cursor-wait",
"forced-colors:border forced-colors:border-[ButtonText]",
"min-h-11 min-w-11",
].join(" "),
{
variants: {
variant: {
primary: "bg-accent text-accent-fg hover:bg-accent-hover",
secondary: "bg-surface text-fg border border-border hover:bg-surface-raised",
ghost: "bg-transparent text-fg hover:bg-surface-raised",
danger: "bg-danger text-white hover:brightness-110",
},
size: { sm: "h-9 px-3 text-sm", md: "h-11 px-4", lg: "h-12 px-6 text-base" },
},
defaultVariants: { variant: "primary", size: "md" },
}
);Every token resolves through DESIGN.md. No magic numbers.
Step 1 — Detect.
bash "${CLAUDE_SKILL_DIR}/scripts/detect-framework.sh"Returns JSON with cssFramework, tailwindVersion, componentLibrary, projectFramework, designMd. Branch on recommendedAdapter.
Step 2 — Load DESIGN.md.
Step 3 — Lint the DESIGN.md.
bash "${CLAUDE_SKILL_DIR}/scripts/lint-design-md.sh" DESIGN.mdIf it fails schema, stop and fix it first. A broken token layer poisons everything downstream.
Step 4 — Generate theme (once per project).
node "${CLAUDE_SKILL_DIR}/scripts/generate-theme.mjs" DESIGN.md --target=<adapter>Emits the framework-native theme file (@theme block, tailwind.config.ts, theme.ts, etc.) wired to the tokens in DESIGN.md. Show the user the diff; get approval before writing.
Step 5 — Build the component.
references/state-matrix.md.references/framework-adapters/.:focus-visible with the double-ring shadow pattern.select-none; mark inert overlays with pointer-events-none.Step 6 — Validate.
bash "${CLAUDE_SKILL_DIR}/scripts/test.sh" <file>Runs validate-tokens, validate-component, quality-score, and — if a reference PNG exists — visual-diff. Blocks on violations; warns on smells; emits a composite score 0–100.
Step 7 — Verify contrast.
node "${CLAUDE_SKILL_DIR}/scripts/contrast-check.mjs" DESIGN.mdWalks every semantic color pair (fg on bg, accent-fg on accent, border on surface) and asserts WCAG 2.2 AA (4.5:1 text, 3:1 large text + UI, 3:1 focus).
Step 8 — Generate the design system showcase page.
node "${CLAUDE_SKILL_DIR}/scripts/generate-design-system-page.mjs" \
DESIGN.md --out src/pages/DesignSystem.tsxRun this once per project after finalizing DESIGN.md, and again whenever the token structure changes (not the values). The resulting page is the visual reference both user and agent come back to throughout the development cycle. Keep it in version control and wire it to a route like /design-system.
Follow references/screenshot-to-code-workflow.md. The 7-pass loop is encoded as filled prompts with concrete JSON schemas. Do not invent tokens — reconcile against DESIGN.md at pass 5 and get user approval on any NEW tokens.
For dense regions:
bash "${CLAUDE_SKILL_DIR}/scripts/crop-region.sh" input.png <x> <y> <w> <h> out.pngCrops produce measurably better vision-model accuracy. Use them.
For verification:
node "${CLAUDE_SKILL_DIR}/scripts/screenshot-component.mjs" http://localhost:3000/my-page out.png
node "${CLAUDE_SKILL_DIR}/scripts/visual-diff.mjs" reference.png out.png diff.png 0.1Iterate until score ≥ 95 (recreation) or ≥ 99 (pixel-perfect port). Cap at 3 iterations — gains plateau.
bash "${CLAUDE_SKILL_DIR}/scripts/audit.sh" src/Walks every component file, emits {file, score, grade, violations[]}, sorts by worst. Fix in order. Re-run and report the delta.
| Violation | Exit |
|---|---|
Literal #hex/rgb()/hsl() outside token file | block |
Inline style={{ color: ... }} | block |
<img> without alt | block |
| File > 300 LOC (tightened in v1.2.0, was 500) | block |
| Longest function > 80 LOC (new in v1.2.0) | block |
File with no focus-visible but has onClick/<button> | block |
| Layout file with no responsive variants (promoted from warn to block in v1.2.0) | block |
| px outside the allowed scale (> 3 occurrences) | block |
| Component file with > 10 hooks (tightened from 12) | block |
| JSX nesting depth > 6 | block |
| Interactive element with no 44×44 minimum size (new in v1.2.0) | warn |
| Component without exported Props interface (new in v1.2.0) | warn |
| Component with module-scope hardcoded data > 3 items (new in v1.2.0) | warn |
| h1/h2/h3 without clamp() or responsive text-\* (new in v1.2.0) | warn |
outline: none without replacement shadow/outline | warn |
Animating width/height/top/left/margin/padding | warn |
:focus used instead of :focus-visible | warn |
Allowed px scale: 0, 1, 2, 3, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 56, 64, 72, 80, 96, 112, 128, 160, 192, 224, 256, plus viewport breakpoints 320, 375, 768, 1024, 1280, 1440, 1536, 1920.
Every layout component must pass at 320, 375, 428, 768, 1024, 1280, 1440, 1920 pixels wide — the full device range from iPhone SE to ultra-wide desktop. The validate-component.sh hook blocks layout files that have:
sm:, md:, lg:, xl:, 2xl:)@container / container queriesauto-fit, minmax(), clamp(), fr units)"Layout file" means any file containing <main>, <section>, <article>, <aside>, <nav>, or className variants of grid, flex-col, flex-row, container, or Layout. Buttons and small primitives are exempt — they inherit responsive behavior from their parents, and forcing breakpoint variants on every button would add noise without value.
Content-first beats breakpoint-first. Start narrow (320px), let content drive breakpoints. Add a breakpoint only when the layout visibly breaks. Prefer container queries over media queries for reusable components (a Card in a sidebar adapts to its container, not the viewport).
For the full responsive playbook — fluid type formulas, container query patterns, intrinsic grid primitives, touch targets, safe-area insets, dvh/svh/lvh, and a self-validation checklist — see references/responsive-patterns.md.
Every component you create must be reusable — droppable into a different context and parameterizable via props. validate-reusability.sh runs on every edit and warns on:
Props interface/type. Declare one: export interface ButtonProps { ... }.const array with > 3 object items. Accept the data as a prop so the component works for other datasets.fetch(), axios.*, useQuery(), useSWR(), or useMutation() directly. Move data fetching into a container or hook and pass data via props. Files under /containers/, /hooks/, /pages/, /routes/, or /app/ are exempt.{children} usage and no destructured props, but is > 30 LOC. It hardcodes its own content and can't be reused.Pages are exempt: files matching pages/, app/*/page.tsx, app/*/layout.tsx, routes/, App.tsx, index.tsx, *.stories.tsx, *.test.tsx, and DesignSystem.tsx / design-system/ are skipped — hardcoded content is correct in those files by design.
| Metric | Hard (block) | Soft (warn) | Old (v1.1.0) |
|---|---|---|---|
| File LOC | 300 | 150 | 500 / 300 |
| Function LOC (longest) | 80 | 40 | — (no check) |
| Hooks per component | 10 | 6 | 12 / 8 |
| JSX nesting depth | 6 | 4 | 6 / 4 |
Function LOC is tracked with a proper brace-counting awk parser, not a naive line-count — it finds the longest top-level function in a file and reports its LOC. A single 120-LOC function in a 200-LOC file still blocks the edit.
update-ui-memory.sh runs after every component write and appends a structured entry to .claude/super-design/ui-memory.md:
## 2026-04-10T14:22:07Z — src/components/Button.tsx
- LOC: 42
- Tokens: --color-accent, --color-fg, --color-border, --radius-md, --inset-sm
- States: hover, focus-visible, disabled, active, loading
- Responsive: sm, md
- Touch targets: compliant (44×44 min)
- Props interface: ButtonProps (exported)
- Forced-colors: compliantThe log is bounded to the last 200 entries (older ones are pruned automatically) and loaded into session context by inject-design-context.sh. This means across a long development cycle you can see your own past decisions — which tokens you used, which states you covered, what your last Button looked like — without re-reading every file. The agent uses this log to stay consistent across the entire project.
generate-design-system-page.mjs emits a single-file React route that renders every token in DESIGN.md live:
Run it with:
node "${CLAUDE_SKILL_DIR}/scripts/generate-design-system-page.mjs" \
DESIGN.md --out src/pages/DesignSystem.tsxThe generated file references CSS variables via var(--color-*) etc., so it auto-updates when the theme is regenerated without needing to re-run this script. Re-run only when the token STRUCTURE changes (tokens added or removed), not when VALUES change.
The design system page is the single source of truth the user and agent can reference throughout the development cycle. It is exempt from the 300 LOC rule (it's a page, not a component) and from reusability checks (pages are allowed to hardcode content).
Load on demand; each reference is ~400–900 words:
DESIGN.md — the enhanced template (blank slate)references/tokens-schema.md — DTCG format, naming, primitive vs semantic vs component layersreferences/state-matrix.md — required states per component + ARIA + keyboard + STATE_MATRIX.yamlreferences/animation-tokens.md — duration/easing/recipes + reduced-motionreferences/responsive-patterns.md — breakpoints, clamp(), container queries, touch targets, safe-areareferences/component-quality-gates.md — LOC/complexity/scoring rubric + regex patternsreferences/screenshot-to-code-workflow.md — 7-pass extraction loop with filled promptsreferences/framework-adapters/*.md — concrete theme codegen per frameworkscripts/validate-tokens.sh — blocks literal colors, inline styles, off-scale px (PostToolUse hook)scripts/validate-component.sh — blocks oversized files/functions, missing focus-visible, bad responsive, weak touch targets (PostToolUse hook)scripts/validate-reusability.sh — warns on missing Props interface, hardcoded content, module-scope data (PostToolUse hook, new in v1.2.0)scripts/update-ui-memory.sh — maintains .claude/super-design/ui-memory.md, a running log of every component write (PostToolUse hook, new in v1.2.0)scripts/generate-theme.mjs — emits framework-native theme code from DESIGN.mdscripts/generate-design-system-page.mjs — emits a live React showcase page from DESIGN.md (new in v1.2.0)scripts/contrast-check.mjs — WCAG 2.2 AA contrast validator for DESIGN.mdscripts/lint-design-md.sh — schema linter for DESIGN.mdscripts/quality-score.sh — 0–100 per-file quality gradescripts/audit.sh — batch audit walker for src/scripts/test.sh — 13-test self-test suiteOnly load what you need. SKILL.md + the single matching adapter is typically enough for one session.
--color-neutral-900) from components. Reference the semantic layer (--color-fg).:focus — always :focus-visible with a double-ring.outline: none without a same-or-greater-visibility replacement.forced-colors: active fallback on interactive surfaces.lint-design-md.sh at session start.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.