design
SkillMediaDesign system reasoning. Maps product domain to style, palette, typography, and platform-specific patterns. Generates .rune/design-system.md as the shared design contract for all UI-generating skills.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the design skill
What this skill tells your AI
The instructions your AI receives, as published by rune-kit/rune in skills/design/SKILL.md and read by ahel’s review.
Purpose
Design system reasoning layer. Converts a product description into a concrete design system — style, color direction, typography pairing, platform conventions, and an explicit anti-pattern list for this domain. Writes .rune/design-system.md as the persistent design contract that all UI-generating skills read before producing code. Prevents AI-generated UI from defaulting to generic patterns ("purple accent, card grids, centered everything") that signal "not designed by a human."
Triggers
/rune design— manual invocation when starting a new UI project- Called by
cook(L1): frontend task detected, no.rune/design-system.mdexists - Called by
review(L2): AI anti-pattern detected — recommended to run design skill - Called by
perf(L2): Lighthouse Accessibility BLOCK — design foundation may be missing
Calls (outbound)
scout(L2): detect existing design tokens, component library, platform targetsasset-creator(L3): generate base visual assets (logo, OG image) from design systembrowser-pilot(L3): render the surface and inspect it before claiming any visual property holds (Step 5.4)review(L2): accessibility violations found → flag for fix in next code review
Called By (inbound)
cook(L1): before any frontend code generationscaffold(L1): design system for new projectbrainstorm(L2): when selected approach has UI/UX implicationsba(L2): when requirements include UI/UX componentsreview(L2): when AI anti-pattern detected in diffperf(L2): when Lighthouse Accessibility score blocks- User:
/rune designdirect invocation
Output Files
.rune/
└── design-system.md # Design contract for all UI-generating skills
Executable Steps
Step 0 — Load Design Reference
Load the design knowledge base before reasoning:
- Check for user-level override:
~/.claude/docs/design-dna.md- If exists →
Readit. This is the primary reference (user's curated taste).
- If exists →
- If no user override →
Readthe baseline:skills/design/DESIGN-REFERENCE.md(shipped with Rune) - The loaded reference provides: font pairings, chart selection, component architecture, color principles, UX checklist, interaction patterns, anti-pattern signatures
- Apply reference knowledge throughout Steps 3-5 (domain reasoning, token generation, checklist)
- When the domain involves any UI motion (transitions, animations, gestures, springs, micro-interactions) → also
Readskills/design/MOTION-CRAFT.md. It is the canonical motion authority: the should-it-animate frequency gate, easing/duration budgets (including peak-slope curve selection for large travel, and velocity continuity across keyframe joins), physicality (neverscale(0), origin-aware popovers), spring physics, gesture handoff, motion performance, the role→strategy reduced-motion framework, SVG-specific mechanics (user units,pathLength, SVGO), and a reverse-lookup vocabulary. Cite its exact values in the design-system motion section; never approximate curves or durations. When MOTION-CRAFT.md and DESIGN-REFERENCE.md disagree on a motion detail (easing, duration, interaction timing), MOTION-CRAFT.md wins — it is the deeper, motion-specific source; DESIGN-REFERENCE.md's Animation Timing / Interaction Patterns tables are the general baseline.
Advisory motion-audit mode: When asked to "improve the animations" / "make this feel better" / "what could be animated here", operate read-only — survey the motion surface against MOTION-CRAFT.md, report frequency-gated findings (and deliberately rejected candidates), and hand precise recipes to
cook/fix. Suggesting motion everywhere is worse than useless; expect to reject most candidates.
Why two layers: The baseline ships "good enough" universal design knowledge. Users who care about aesthetics create their own
design-dna.mdwith curated palettes, font pairings, and style preferences. The design skill works well with either — it just works better with a curated reference.
External Data Source
Design intelligence data from UI/UX Pro Max (MIT, 42.8k★).
Located at references/ui-pro-max-data/ — 161 palettes, 84 styles, 73 font pairings, 161 reasoning rules, 99 UX guidelines.
When references/ui-pro-max-data/ is available:
- Step 2: query
styles.csvfor domain-matched visual styles (expands from 10 → 84) - Step 3: query
ui-reasoning.csvfor industry-specific design rules (161 rules) - Step 3: query
colors.csvfor palette alternatives (expands from 10 → 161) - Step 6 (Anti-AI): cross-check proposed style against reasoning DB — if flagged as "AI-generic", suggest 3 alternatives
Step 1 — Discover
Invoke scout to detect:
- Platform target:
web|ios(SwiftUI) |android(Compose) |react-native|multi-platform - Existing design tokens: check for
tokens.json,design-system/,theme.ts,tailwind.config.*,variables.css - Component library in use: shadcn/ui | Radix | MUI | Ant Design | custom | none
- Framework: Next.js | Vite+React | SvelteKit | Vue | SwiftUI | Jetpack Compose | other
If .rune/design-system.md already exists: Read it, check Last Updated date. If < 30 days old, ask user whether to refresh or keep. Do NOT silently overwrite.
Step 2 — Classify Product Domain
From the user's task description + codebase context, classify product type:
| Category | Examples |
|---|---|
| Trading/Fintech | trading dashboard, portfolio tracker, payment app, crypto wallet |
| SaaS Dashboard | admin panel, analytics, CRM, project management |
| Landing/Marketing | landing page, product site, marketing page, waitlist |
| Healthcare | patient portal, medical dashboard, health tracker |
| E-commerce | product catalog, cart, checkout, marketplace |
| Developer Tools | IDE plugin, CLI dashboard, API explorer, devtool |
| Creative/Portfolio | portfolio, design showcase, art gallery, agency site |
| Social/Community | social feed, forum, messaging, community platform |
| Mobile Consumer | iOS/Android consumer app — entertainment, productivity, lifestyle |
| AI-Native | AI assistant interface, chatbot, model explorer |
If domain is unclear: ask one clarifying question — "Is this closer to X or Y?"
Step 2.5 — Mood-to-Constraint Mapping
After classifying domain, ask ONE question: "What should users feel when they use this?"
Accept a single mood keyword (or infer from context if obvious). Map mood to concrete design constraints:
| Mood | Color Temp | Typography Weight | Whitespace | Animation | Shadow |
|---|---|---|---|---|---|
| Impressed | Cool (blue-slate) | Heavy display (700-800) | Generous (xl-3xl) | Dramatic reveals (0.8-1.2s ease-out) | Deep, layered |
| Excited | Warm (amber-orange) | Bold contrasts (400 vs 800) | Tight-medium (sm-lg) | Energetic springs (0.4-0.6s spring) | Elevation lifts |
| Calm | Neutral-warm (stone-sage) | Light-medium (300-500) | Very generous (2xl-3xl) | Slow fades (0.6-0.8s ease-out-quad) | Soft, minimal |
| Confident | Cool-neutral (zinc-slate) | Medium-heavy (500-700) | Structured (md-xl) | Precise slides (0.3-0.5s ease) | Crisp, defined |
| Playful | Saturated (multi-hue) | Round + bold (600-700) | Medium, irregular (md-lg) | Bouncy springs (0.4-0.6s spring, overshoot) | Hard/comic (3-5px offset) |
| Techy | Cold (gray-cyan) | Mono-heavy, crisp (400-600) | Dense, grid-aligned (sm-md) | Sharp snaps (0.15-0.3s ease-out) | Minimal or glow |
| Professional | Muted neutrals | System fonts, readable (400-500) | Balanced (md-lg) | Subtle (0.2-0.3s ease) | Standard elevation |
| Inspired | Rich-warm (gold-terracotta) | Editorial display (300-700 range) | Asymmetric, generous | Scroll-driven reveals (0.5-0.8s) | Dramatic, directional |
Mapping rules:
- Mood constraints OVERRIDE generic domain defaults where they conflict (mood is user intent, domain is convention)
- If mood contradicts domain safety (e.g., "Playful" + Healthcare), WARN user: "Playful tone may reduce trust in medical context — proceed?"
- Write selected mood + resolved constraints to
.rune/design-system.mdunder## Moodsection - Downstream skills (
animation-patterns,palette-picker,type-system) read mood constraints from design-system.md
Skip if: User says "no preference" or "just follow domain defaults" — proceed to Step 3 with domain-only reasoning.
Step 2.7 — Tweaks, Not Menus (Default Style Pattern)
Picking from a 10-option style menu is how AI UI gets generic. Instead:
- Propose ONE opinionated default based on domain + mood (from Step 2.5). Describe it in 2-3 lines — style, palette direction, typography pairing.
- Ask for tweaks, not choices. The question is "Any tweaks to this, or ship it?" — not "Which of these do you prefer?"
- Accept natural-language adjustments. Map phrases → design system edits:
- "more professional" → heavier type weights, reduce saturation, tighter spacing
- "less corporate" → looser weights, brighter accent, more whitespace
- "darker" → swap base for darker neutral, raise contrast on elevated surfaces
- "more playful" → add subtle animation, soften corners, bolder accent
- "more trust" → cooler palette (slate/blue), heavier headers, smaller radius
- If the user asks for a menu, provide max 3 options — but mark one as the recommended default. Never present a neutral list of 5+ equivalent styles.
Why: Every menu option dilutes commitment. A single confident default gets committed, tweaked, and shipped. A menu gets deliberated, A/B'd, and abandoned. This is the Tweaks Default pattern from Anthropic's design system guidance — the AI commits first, humans steer second.
Step 2.9 — Universal Anti-AI Rules (apply to ALL domains)
These rules apply regardless of domain, mood, or platform. Every generated design system MUST comply.
Enforcement: rune:review v1.1.0+ reads .rune/design-system.md § Scale Minimums and flags violations of Rules 1–3 below as MEDIUM/HIGH findings. Rules 4–6 (Measurable Constraints, No-Pure-No-Lorem, CJK-First) are design-time guidance — added in design v0.6.0, review enforcement forthcoming. Design defines, review enforces — this is the contract.
Rule 1 — Scale Minimums
Below these thresholds, designs read as "AI boilerplate" no matter how good the palette is.
| Element | Minimum | Ideal |
|---|---|---|
| Hero/display text | 48px | 56-72px |
| H1 (page title) | 32px | 36-40px |
| Body text | 16px (never 14px for primary content) | 16-18px |
| Secondary/meta text | 14px | 14-15px |
| Touch targets (mobile) | 44×44px | 48×48px |
| Touch target gap (mobile) | 8px | 12px |
| Focus-visible ring | 2px | 3px |
Write these minimums to .rune/design-system.md under ## Scale Minimums. Downstream skills (cook, fix) treat violations as review findings.
Rule 2 — Placeholder Over Bad SVG
If the design calls for an icon, illustration, or graphic that the agent cannot generate at high quality, ship a boxed placeholder, not a malformed SVG.
<!-- GOOD: placeholder -->
<div class="placeholder" data-icon="dashboard" aria-label="Dashboard icon — design pass needed">
[ ICON: dashboard ]
</div>
<!-- BAD: AI-generated SVG with broken geometry -->
<svg viewBox="0 0 24 24">
<path d="M12 2L2 7l10 5 10-5-10-5z M2 17l10 5 10-5 M2 12l10 5 10-5"/>
</svg>
- Use Phosphor Icons (
@phosphor-icons/react) or Huge Icons as the library default. Never generate custom SVG for standard iconography. - For illustrations, reference a placeholder string (e.g.,
[ILLUSTRATION: empty-state-dashboard]) that a human or asset-creator pass fills in later. - Malformed SVG is the #1 AI tell. A clean labeled placeholder is honest and professional.
Placeholder Ownership (MANDATORY): every placeholder or intentionally inert element the design ships — [ ICON: ... ], [ILLUSTRATION: ...], [ PLACEHOLDER: ... ], and any button/link/form rendered as visual-only (no behavior designed yet) — MUST be listed in .rune/ui-spec.md under a ## Unwired Elements section:
## Unwired Elements
| Element | Location | Why unwired | Owner of wiring |
|---------|----------|-------------|-----------------|
| product-grid | ProductGrid.tsx | awaiting US-2 backend | US-2 Endpoint task |
| [ ICON: dashboard ] | Sidebar.tsx | asset pass pending | asset-creator |
This list is how downstream gates tell declared debt from accidental dead UI: preflight skips these elements, verification reports them as INFO (visible, non-failing), and converge counts them as missing until wired. A placeholder NOT on this list that reaches implementation = a dead element with no owner — that's the bug this section exists to prevent.
Rule 3 — Color Derivation via oklch(), not Manual Shading
When the design needs a darker hover, lighter surface, or tinted state, derive from the accent via oklch() — never eyeball a hex value.
/* GOOD: relative derivation */
--accent: oklch(65% 0.2 255);
--accent-hover: oklch(from var(--accent) calc(l - 0.08) c h);
--accent-pressed: oklch(from var(--accent) calc(l - 0.15) c h);
--accent-subtle: oklch(from var(--accent) calc(l + 0.3) calc(c * 0.4) h);
/* BAD: manual hex shading — breaks hue/chroma consistency */
--accent: #3b82f6;
--accent-hover: #2563eb; /* guessed darker */
Why: HSL shading distorts perceived brightness at different hues. oklch() keeps perceptual lightness consistent, so derived states look intentional rather than "kinda close." Write derived tokens to .rune/design-system.md — downstream skills reuse these, not re-derive.
Bonus: use text-wrap: pretty on headings to prevent widow words. One line, zero ceremony.
Rule 4 — Measurable Constraints, Not Vague Directives
Every design rule written into .rune/design-system.md MUST be measurable. Vague directives are not constraints — they are decoration. A reviewer cannot enforce "use modern typography"; they CAN enforce "Inter 96/64/40/24/16 px on an 8 px grid."
| Vague (reject) | Measurable (accept) |
|---|---|
| "Use modern typography" | "Inter 96/64/40/24/16 px on an 8 px grid" |
| "Subtle shadows" | "0 1px 2px rgba(0,0,0,0.05) (sm), 0 4px 6px rgba(0,0,0,0.07) (md)" |
| "Brand-aligned color" | "Accent: oklch(65% 0.2 255); hover: oklch(from var(--accent) calc(l - 0.08) c h)" |
| "Good contrast" | "All text/bg pairs ≥ 4.5:1 (WCAG AA), large text ≥ 3:1" |
| "Tasteful spacing" | "8 px grid: every margin, padding, line-height a multiple of 8" |
| "Real content, not lorem ipsum" | "Use the user's actual data; if missing, ship a labelled [ PLACEHOLDER: content-type ] block" |
Rule 5 — No Pure Black, No Pure White, No Lorem Ipsum
Three small forbids that catch the highest-frequency AI tells:
- No
#000or#ffffor any default text or background. Both crush perceived depth and read as "default browser styles." Useoklch(98% 0 0)/oklch(8% 0 0)(or domain-appropriate neutrals) and derive surfaces from them. - No lorem ipsum / "Lorem ipsum dolor" anywhere in shipped output. Either use the user's real data, or ship a labelled
[ PLACEHOLDER: hero-headline ]block (same pattern as Rule 2 SVG placeholder). Lorem ipsum is the #2 AI tell after malformed SVG. - No
outline: nonewithout a:focus-visiblereplacement. Already covered by Pre-Delivery Checklist; restated here so it lives next to the other two highest-impact forbids.
Rule 6 — CJK-First Font Stack (Multi-Language Products Only)
If the product ships in Chinese / Japanese / Korean (or mixes CJK with Latin), the font stack MUST list a CJK-capable family FIRST, with Latin as fallback:
/* GOOD: CJK-first, Latin fallback */
font-family: "Noto Sans SC", "Source Han Sans SC", "Inter", system-ui, sans-serif;
/* BAD: Latin-first — Chinese characters render in browser fallback (PingFang, Heiti) and break rhythm */
font-family: "Inter", "Noto Sans SC", system-ui;
For prose / serif: "Noto Serif SC" / "Source Han Serif SC" / "Manrope". For monospace: "JetBrains Mono" / "Sarasa Mono SC" (Sarasa unifies CJK + Latin metrics). Skip this rule entirely if the product is Latin-only — listing CJK fonts you don't need slows first-paint.
Step 3 — Apply Domain Reasoning Rules
Map domain to design system parameters:
Trading/Fintech:
Style: Data-Dense Dark
Palette: Neutral dark (#0c1419 bg), semantic colors ONLY for profit/loss
Profit: #00d084 (green) | Loss: #ff6b6b (red)
Accent: #2196f3 (data highlight) — NOT purple
Typography: JetBrains Mono 700 for ALL numeric values (prices, P&L, %)
Inter 400 for labels, Inter 600 for headings
Effects: Subtle grid lines, real-time pulse animations on live data
Anti-patterns:
❌ Gradient washes on data tables (obscures precision)
❌ Accent colors that conflict with profit/loss signal colors
❌ Decorative motion (distracts from live data)
❌ Dark-on-dark text for secondary labels (contrast required)
SaaS Dashboard:
Style: Minimalism or Flat Design
Palette: Professional neutrals, single brand accent (NOT purple unless brand)
Light: #ffffff bg, #f8fafc surface | Dark: #0f172a bg, #1e293b surface
Accent: brand-defined — default #6366f1 is acceptable here as a SaaS pattern
Typography: Inter 400/500/600 throughout — consistent, readable, data-friendly
Space Grotesk 700 for hero/display only
Effects: Skeleton loaders, subtle hover states, clean data tables
Anti-patterns:
❌ Card-grid monotony (every section same layout)
❌ Animations that delay data visibility
❌ Missing empty/error states in data tables
Landing/Marketing:
Style: Glassmorphism (current era) or Aurora/Mesh
Palette: Brand-expressive — this is the ONE context where bold palette is correct
High-contrast CTAs (must pass 4.5:1 contrast on all backgrounds)
Typography: Space Grotesk 700 for hero display (48–72px)
Inter 400/500 for body — max line-width 720px
Effects: Animated mesh gradients, floating glass cards, scroll-triggered reveals
Anti-patterns:
❌ Generic hero: "big text + diagonal purple-to-blue gradient" — AI signature
❌ Centered layout throughout (breaks directional reading flow)
❌ Missing scroll animations on a static page
❌ CTAs that don't stand out from body copy
Healthcare:
Style: Trust & Authority (clean, clinical, accessible)
Palette: Clean blue/white/green — NO red except clinical alerts
#f0f9ff bg, #1e40af accent, #059669 success, #dc2626 CRITICAL_ONLY
Typography: Inter throughout — never decorative fonts
Body minimum 16px for readability by older/impaired users
Effects: Minimal — subtle hover, no motion by default
Anti-patterns:
❌ Dark mode as default (patients/elderly → light mode)
❌ Gamification patterns (inappropriate for medical context)
❌ Red for informational messages (reserved for clinical alerts)
❌ Dense data layouts without clear visual hierarchy
E-commerce:
Style: Conversion-Optimized (Warm Minimalism)
Palette: Warm neutrals, high-contrast CTAs
Urgency signals: #ef4444 for "low stock", #f59e0b for "sale"
Typography: Bold product names (Space Grotesk 600+), readable descriptions (Inter 400)
Effects: Hover zoom on product images, add-to-cart pulse, trust badges
Anti-patterns:
❌ Cluttered above-fold (too many competing CTAs)
❌ Add to cart button that doesn't stand out
❌ Missing product image zoom/gallery
❌ Checkout flow with more than 3 steps visible at once
Developer Tools:
Style: Minimalism or Neubrutalism
Palette: Dark mode default — #0d1117 bg (GitHub-scale), #161b22 surface
Syntax highlighting colors as accent palette
No heavy gradients — developers recognize and distrust decorative UI
Typography: JetBrains Mono for code/commands, Inter for prose
Effects: Keyboard shortcuts visible, dense information layout OK
Anti-patterns:
❌ Decorative animations that delay tool response
❌ Non-monospace font for code blocks or command output
❌ Light mode only (developer tools default to dark)
❌ Visual noise around core functionality
Creative/Portfolio:
Style: Editorial Grid or Glassmorphism or Brutalism (brand-specific)
Palette: MUST be distinctive — generic palettes are disqualifying
This is the one category where custom/unusual palettes are required
Typography: Custom or display font as headline (NOT Inter alone)
Font pairing must have contrast: Display + neutral body
Effects: Curated — hover reveals, scroll-based reveals, cursor effects
Anti-patterns:
❌ Generic card grid with equal padding everywhere
❌ Inter-only typography (zero personality)
❌ Stock photo backgrounds
❌ Navigation that looks like every other portfolio
AI-Native:
Style: Minimal Functional or Glassmorphism
Palette: Purple/violet IS acceptable here (it is the AI-native signal)
#7c3aed accent, dark neutral bg, subtle gradients
Typography: Inter throughout — clarity over personality
Effects: Typing indicators, streaming text, thinking states
Anti-patterns:
❌ Purple on non-AI product (exports the AI signal to inappropriate contexts)
❌ Static empty states — AI interfaces must show "thinking" states
❌ Missing latency UX (skeleton during generation, cancel button)
Step 4 — Platform-Specific Overrides
Apply platform conventions on top of domain rules:
iOS (SwiftUI / iOS 26+):
Visual language: Liquid Glass — translucent surfaces with backdrop blur
background: UIBlurEffect or .regularMaterial
border: subtle 1px rgba(white, 0.15) — NOT solid
roundness: aggressive corner radius (16–24px on cards, full on buttons)
Icons: SF Symbols ONLY — not Heroicons, not Lucide
Typography: SF Pro family — Dynamic Type scaling is mandatory
Safe areas: Content must respect safeAreaInsets on all edges
Anti-patterns:
❌ Solid-background cards (deprecated in iOS 26 Liquid Glass era)
❌ Custom icon fonts (SF Symbols is the platform contract)
❌ Fixed font sizes (Dynamic Type must be supported)
Android (Jetpack Compose / Material 3 Expressive):
Color: MaterialTheme.colorScheme — dynamic color derived from wallpaper
NEVER hardcode hex colors in Compose — use semantic tokens
Shape: Extreme corner expressiveness — use shape variation as affordance signal
Small interactive: RoundedCornerShape(4dp)
Cards/surfaces: RoundedCornerShape(16dp)
FABs: CircleShape
Motion: Spring physics — tween() is almost never the right choice
spring(dampingRatio = Spring.DampingRatioMediumBouncy)
Anti-patterns:
❌ Hardcoded hex colors (breaks dynamic color contract)
❌ Linear easing (Material 3 Expressive uses spring physics)
❌ Small corner radii (shape expressiveness is a key M3 Expressive principle)
Web:
- Apply domain rules from Step 3
- Default: dark mode support required (
prefers-color-scheme: dark) - Responsive: must design for 375px, 768px, 1024px, 1440px breakpoints
- Accessibility: WCAG 2.2 AA minimum
Step 5 — Generate Design System File
Use Write to create .rune/design-system.md:
# Design System: [Project Name]
Last Updated: [YYYY-MM-DD]
Platform: [web | ios | android | multi-platform]
Domain: [product category]
Style: [chosen style]
## Color Tokens
### Primitive (raw values)
--color-[name]-[scale]: [hex]
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 86
- Forks
- 26
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
design-rune-kit- Source
- github.com/rune-kit/rune