design

SkillMedia

Design 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.

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.md exists
  • 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 targets
  • asset-creator (L3): generate base visual assets (logo, OG image) from design system
  • browser-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 generation
  • scaffold (L1): design system for new project
  • brainstorm (L2): when selected approach has UI/UX implications
  • ba (L2): when requirements include UI/UX components
  • review (L2): when AI anti-pattern detected in diff
  • perf (L2): when Lighthouse Accessibility score blocks
  • User: /rune design direct 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:

  1. Check for user-level override: ~/.claude/docs/design-dna.md
    • If exists → Read it. This is the primary reference (user's curated taste).
  2. If no user override → Read the baseline: skills/design/DESIGN-REFERENCE.md (shipped with Rune)
  3. The loaded reference provides: font pairings, chart selection, component architecture, color principles, UX checklist, interaction patterns, anti-pattern signatures
  4. Apply reference knowledge throughout Steps 3-5 (domain reasoning, token generation, checklist)
  5. When the domain involves any UI motion (transitions, animations, gestures, springs, micro-interactions) → also Read skills/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 (never scale(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.md with 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.csv for domain-matched visual styles (expands from 10 → 84)
  • Step 3: query ui-reasoning.csv for industry-specific design rules (161 rules)
  • Step 3: query colors.csv for 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:

CategoryExamples
Trading/Fintechtrading dashboard, portfolio tracker, payment app, crypto wallet
SaaS Dashboardadmin panel, analytics, CRM, project management
Landing/Marketinglanding page, product site, marketing page, waitlist
Healthcarepatient portal, medical dashboard, health tracker
E-commerceproduct catalog, cart, checkout, marketplace
Developer ToolsIDE plugin, CLI dashboard, API explorer, devtool
Creative/Portfolioportfolio, design showcase, art gallery, agency site
Social/Communitysocial feed, forum, messaging, community platform
Mobile ConsumeriOS/Android consumer app — entertainment, productivity, lifestyle
AI-NativeAI 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:

MoodColor TempTypography WeightWhitespaceAnimationShadow
ImpressedCool (blue-slate)Heavy display (700-800)Generous (xl-3xl)Dramatic reveals (0.8-1.2s ease-out)Deep, layered
ExcitedWarm (amber-orange)Bold contrasts (400 vs 800)Tight-medium (sm-lg)Energetic springs (0.4-0.6s spring)Elevation lifts
CalmNeutral-warm (stone-sage)Light-medium (300-500)Very generous (2xl-3xl)Slow fades (0.6-0.8s ease-out-quad)Soft, minimal
ConfidentCool-neutral (zinc-slate)Medium-heavy (500-700)Structured (md-xl)Precise slides (0.3-0.5s ease)Crisp, defined
PlayfulSaturated (multi-hue)Round + bold (600-700)Medium, irregular (md-lg)Bouncy springs (0.4-0.6s spring, overshoot)Hard/comic (3-5px offset)
TechyCold (gray-cyan)Mono-heavy, crisp (400-600)Dense, grid-aligned (sm-md)Sharp snaps (0.15-0.3s ease-out)Minimal or glow
ProfessionalMuted neutralsSystem fonts, readable (400-500)Balanced (md-lg)Subtle (0.2-0.3s ease)Standard elevation
InspiredRich-warm (gold-terracotta)Editorial display (300-700 range)Asymmetric, generousScroll-driven reveals (0.5-0.8s)Dramatic, directional

Mapping rules:

  1. Mood constraints OVERRIDE generic domain defaults where they conflict (mood is user intent, domain is convention)
  2. If mood contradicts domain safety (e.g., "Playful" + Healthcare), WARN user: "Playful tone may reduce trust in medical context — proceed?"
  3. Write selected mood + resolved constraints to .rune/design-system.md under ## Mood section
  4. 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:

  1. Propose ONE opinionated default based on domain + mood (from Step 2.5). Describe it in 2-3 lines — style, palette direction, typography pairing.
  2. Ask for tweaks, not choices. The question is "Any tweaks to this, or ship it?" — not "Which of these do you prefer?"
  3. 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
  4. 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.

ElementMinimumIdeal
Hero/display text48px56-72px
H1 (page title)32px36-40px
Body text16px (never 14px for primary content)16-18px
Secondary/meta text14px14-15px
Touch targets (mobile)44×44px48×48px
Touch target gap (mobile)8px12px
Focus-visible ring2px3px

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:

  1. No #000 or #fff for any default text or background. Both crush perceived depth and read as "default browser styles." Use oklch(98% 0 0) / oklch(8% 0 0) (or domain-appropriate neutrals) and derive surfaces from them.
  2. 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.
  3. No outline: none without a :focus-visible replacement. 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