Skip to content
frontend-design-svelte logo

Frontend Design Svelte Skill

frontend-design-svelte

Create distinctive, production-grade Svelte/TypeScript frontends with exceptional design quality

SKILL.md

Full skill instructions

Frontend Design Svelte Skill

Purpose

This skill guides the creation of distinctive, production-grade Svelte frontends that combine Svelte's reactive elegance with exceptional design quality. It integrates all design frameworks: intentional thinking, typography, color, motion, spatial composition, and anti-pattern awareness.

When to Use

  • Building production Svelte/​SvelteKit frontends
  • Creating component libraries with design personality
  • Designing interactions that leverage Svelte's reactivity
  • Building accessible, mobile-first web applications
  • Prototyping high-fidelity designs in code

Core Principles

1. Design Thinking Foundation (Pre-Coding)

Before writing any code, establish intentional design direction:

The Four Critical Questions:

  1. Purpose: What problem are we solving? Who are we solving it for?
  2. Tone: What emotional response do we want? What aesthetic direction reflects this?
  3. Constraints: What are the real technical, temporal, or business limits?
  4. Differentiation: What one unforgettable element makes this distinctly ours?

2. Anti-Generic AI Design Standards

Deliberately reject these patterns:

Typography:

  • ❌ Avoid: Inter, Roboto, Open Sans as primary choices
  • ✅ Prefer: Playfair Display, Crimson Pro, Space Grotesk, IBM Plex, Bricolage Grotesque
  • ✅ Use high-contrast pairings: Display + Mono, Serif + Geometric Sans
  • ✅ Use size jumps of 3x+, not incremental 1.5x scaling

Color & Theme:

  • ❌ Avoid: Material Design trinity (blue, red, green)
  • ❌ Avoid: Default SaaS blue (#0099ff) everywhere
  • ✅ Prefer: Intentional palettes with one unexpected accent
  • ✅ Prefer: Warm or cool personality, never neutral grays

Layout & Space:

  • ❌ Avoid: Centered, symmetrical "cookie-cutter" layouts
  • ✅ Prefer: Asymmetrical compositions with intentional whitespace
  • ✅ Use consistent spacing scale: 8px, 12px, 16px, 24px, 32px, 48px, 64px

Motion:

  • ❌ Avoid: Linear timing, instantaneous interactions
  • ✅ Prefer: Orchestrated animations with easing functions
  • ✅ Prefer: Staggered reveals, delightful hover surprises

Svelte-Specific Guidance

TypeScript Setup

Always use TypeScript in Svelte components:

<script lang="ts">
  import type { ComponentProps } from 'svelte'

  interface Props {
    title: string
    count: number
    onAction?: () => void
  }

  let { title, count, onAction }: Props = $props()
</​script>

Reactivity with $:

Leverage Svelte's reactive declarations for dynamic styling and state:

<script lang="ts">
  let theme: 'light' | 'dark' = $state('light')
  let isHovered = $state(false)

  // Reactive computed values
  let backgroundColor = $derived(
    theme === 'light' ? 'var(--color-bg-light)' : 'var(--color-bg-dark)'
  )

  let shadowIntensity = $derived(isHovered ? '0.2' : '0.1')
</​script>

Scoped Styles with CSS Variables

Svelte's scoped styles are default. Use CSS custom properties for theming:

<style>
  :global(:root) {
    --color-primary: #8b4513;
    --color-accent: #d4a574;
    --color-bg: #faf8f3;
    --font-display: 'Playfair Display', serif;
    --font-body: 'IBM Plex Sans', sans-serif;
    --spacing-unit: 8px;
  }

  .card {
    background: var(--color-bg);
    padding: calc(var(--spacing-unit) * 3);
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, var(--shadow-intensity));
    transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  }

  .card:hover {
    --shadow-intensity: 0.15;
    transform: translateY(-4px);
  }
</​style>

Svelte Transitions & Animations

Use Svelte's built-in transitions for elegant animations:

<script lang="ts">
  import { fade, fly, scale, slide } from 'svelte/​transition'
  import { cubicOut, elasticOut } from 'svelte/​easing'

  let isVisible = $state(true)
  let showDetails = $state(false)
</​script>

<!-- Fade in on mount -->
<div in:fade={{ duration: 300 }} out:fade={{ duration: 200 }}>
  Content
</​div>

<!-- Orchestrated entrance with stagger -->
<div
  in:fly={{ y: 50, duration: 600, delay: 100, easing: cubicOut }}
  out:fly={{ y: 20, duration: 300 }}
>
  Hero section
</​div>

<!-- Elastic expand on interaction -->
{#if showDetails}
  <div
    in:scale={{ start: 0.95, duration: 400, easing: elasticOut }}
    out:scale={{ duration: 200 }}
  >
    Detailed content
  </​div>
{/​if}

<!-- Slide for list items (staggered) -->
<ul>
  {#each items as item (item.id)}
    <li
      in:slide={{ duration: 400, delay: index * 50 }}
      out:slide={{ duration: 200 }}
    >
      {item.name}
    </​li>
  {/​each}
</​ul>

Stores for Global State & Theme Management

Use Svelte stores for theme, animations, and global UI state:

<!-- lib/​stores/​theme.ts -->
import { writable, derived } from 'svelte/​store'

export const isDarkMode = writable(false)

export const themeVariables = derived(isDarkMode, ($isDarkMode) => ({
  bgColor: $isDarkMode ? '#1a1a1a' : '#faf8f3',
  textColor: $isDarkMode ? '#f5f5f5' : '#333333',
  accentColor: '#d4a574',
  shadows: $isDarkMode ? 'rgba(0,0,0,0.4)' : 'rgba(0,0,0,0.1)',
}))

<!-- Usage in component -->
<script lang="ts">
  import { isDarkMode, themeVariables } from '$lib/​stores/​theme'
</​script>

<div style:background-color={$themeVariables.bgColor}>
  Content
</​div>

Accessibility & Semantic HTML

Svelte's approach to accessibility:

<script lang="ts">
  let isMenuOpen = $state(false)
  let focusedIndex = $state(-1)
</​script>

<!-- Semantic structure -->
<nav aria-label="Main navigation">
  <button
    aria-expanded={isMenuOpen}
    aria-controls="main-menu"
    aria-label="Toggle navigation menu"
  >
    Menu
  </​button>

  <ul id="main-menu" role="menubar" hidden={!isMenuOpen}>
    {#each menuItems as item (item.id)}
      <li role="none">
        <a href={item.href} role="menuitem">
          {item.label}
        </​a>
      </​li>
    {/​each}
  </​ul>
</​nav>

<!-- Form accessibility -->
<form>
  <label for="email">Email address</​label>
  <input
    id="email"
    type="email"
    required
    aria-required="true"
    aria-describedby="email-hint"
  />
  <small id="email-hint">We'll never share your email.</​small>
</​form>

Mobile-First Responsive Design

Use Svelte's class directives and media queries:

<script lang="ts">
  let viewport: 'mobile' | 'tablet' | 'desktop' = $state('mobile')
  let windowWidth = $state(0)

  $effect(() => {
    if (windowWidth < 640) viewport = 'mobile'
    else if (windowWidth < 1024) viewport = 'tablet'
    else viewport = 'desktop'
  })
</​script>

<svelte:window bind:innerWidth={windowWidth} />

<div class="container" class:is-mobile={viewport === 'mobile'}>
  <header class:is-compact={viewport === 'mobile'}>
    <!-- Mobile-optimized header -->
  </​header>
</​div>

<style>
  .container {
    padding: calc(var(--spacing-unit) * 4);
  }

  .container.is-mobile {
    padding: calc(var(--spacing-unit) * 2);
  }

  header.is-compact {
    font-size: 18px;
  }

  @media (min-width: 640px) {
    header {
      font-size: 24px;
    }
  }
</​style>

8-Phase Development Workflow

Phase 1: Design Thinking & Intent Definition

Input: Feature requirements, target users, problem statement

Actions:

  • Answer the 4 Critical Questions (Purpose, Tone, Constraints, Differentiation)
  • Define emotional intent (trustworthy, energetic, sophisticated, direct, warm, bold)
  • Document design constraints (technical, temporal, business, creative)
  • Identify the unforgettable element that makes this distinctly yours

Deliverable: Design brief with clear direction

Phase 2: Design System & Token Definition

Input: Design brief and tone direction

Actions:

  • Define typography: Display font, Body font, Monospace font
  • Create color palette: Base colors, accents, semantic colors (success, error, warning)
  • Establish spacing scale: 8px increments (8, 12, 16, 24, 32, 48, 64)
  • Define motion easing curves and durations
  • Plan component system structure

Deliverable: Design tokens in CSS variables and Svelte stores

<!-- $lib/​styles/​tokens.css -->
:root {
  /​* Typography */
  --font-display: 'Playfair Display', serif;
  --font-body: 'IBM Plex Sans', sans-serif;
  --font-mono: 'JetBrains Mono', monospace;

  --size-display: 88px;
  --size-h1: 48px;
  --size-h2: 28px;
  --size-body: 16px;
  --size-small: 12px;

  /​* Colors */
  --color-bg: #faf8f3;
  --color-text: #2a2a2a;
  --color-accent: #d4a574;
  --color-accent-dark: #8b4513;

  /​* Motion */
  --easing-out: cubic-bezier(0.16, 0.04, 0.04, 1);
  --easing-elastic: cubic-bezier(0.34, 1.56, 0.64, 1);
  --duration-quick: 200ms;
  --duration-standard: 400ms;
  --duration-slow: 600ms;
}

Phase 3: Component Architecture & TypeScript Contracts

Input: Design tokens and feature requirements

Actions:

  • Define component props with TypeScript interfaces
  • Create component hierarchy (atoms → molecules → organisms)
  • Plan state management strategy
  • Define event handling patterns
  • Document component accessibility requirements

Deliverable: Typed component structure

<!-- lib/​components/​Button.svelte -->
<script lang="ts">
  import { cubicOut } from 'svelte/​easing'

  interface Props {
    variant?: 'primary' | 'secondary' | 'outline'
    size?: 'small' | 'medium' | 'large'
    disabled?: boolean
    ariaLabel?: string
    onclick?: () => void
  }

  let {
    variant = 'primary',
    size = 'medium',
    disabled = false,
    ariaLabel,
    onclick,
  }: Props = $props()
</​script>

<button
  class="button {variant} {size}"
  {disabled}
  aria-label={ariaLabel}
  on:click={onclick}
  in:scale={{ start: 0.95, duration: 200, easing: cubicOut }}
>
  <slot />
</​button>

Phase 4: Interaction & Motion Design

Input: Component structure and design tokens

Actions:

  • Map Svelte transitions to design intent
  • Plan orchestrated page load sequences (staggered reveals)
  • Define hover/​focus states with motion
  • Plan scroll trigger animations
  • Create state-based animations for interactions

Deliverable: Transition patterns and animation sequences

Phase 5: Responsive Design & Layout System

Input: Component library and motion patterns

Actions:

  • Build mobile-first CSS grid/​flex layout system
  • Define breakpoints and responsive behaviors
  • Create viewport-aware components
  • Test touch interactions on mobile
  • Ensure all animations perform well on mobile devices

Deliverable: Responsive component library

Phase 6: Theming & Color Implementation

Input: Design tokens and component library

Actions:

  • Implement CSS variable theming system
  • Create light/​dark mode support (if needed)
  • Apply color palette to components
  • Ensure sufficient color contrast (WCAG AA minimum)
  • Create dynamic theme switcher

Deliverable: Fully themed component system

Phase 7: Accessibility & ARIA Implementation

Input: All components and interactions

Actions:

  • Add semantic HTML structure
  • Implement ARIA labels and roles
  • Test keyboard navigation
  • Ensure focus states are visible
  • Validate against WCAG 2.1 AA standards
  • Test with screen readers

Deliverable: Fully accessible component library

Phase 8: Polish & Performance

Input: Complete feature implementation

Actions:

  • Optimize animation performance (use will-change, GPU acceleration)
  • Add micro-interactions and easter eggs
  • Test on real devices and browsers
  • Measure Core Web Vitals
  • Refine motion based on performance data
  • Final design review against intent

Deliverable: Production-ready application

Anti-Generic-AI Checklist

Use these checks before finalizing any design or component:

Typography:

  • YES to high-contrast font pairings (Display + Mono, Serif + Sans)
  • YES to size jumps of 3x+ (88px, 48px, 28px, 16px)
  • YES to weight extremes (300/​700 vs 400/​600)
  • NO to Inter, Roboto, Open Sans as primary choice

Color & Theme:

  • YES to intentional palette with personality
  • YES to one unexpected accent color
  • YES to warm or cool personality (not neutral)
  • NO to Material Design trinity or default SaaS blue

Layout & Space:

  • YES to asymmetrical compositions
  • YES to generous whitespace with intent
  • YES to consistent spacing scale (8px increments)
  • NO to centered, symmetrical "cookie-cutter" layouts

Motion & Animation:

  • YES to Svelte transitions for smooth animations
  • YES to orchestrated/​staggered reveals
  • YES to easing functions (elastic, cubic-bezier)
  • YES to reactive declarations for dynamic styling
  • YES to scoped styles with CSS variables
  • NO to linear timing or instant interactions
  • NO to animation-heavy design that distracts

Svelte-Specific:

  • YES to TypeScript in <script lang="ts">
  • YES to reactive declarations with $:
  • YES to scoped styles with CSS variables
  • YES to Svelte transitions for elegant motion
  • YES to stores for global state and theme
  • YES to semantic HTML and ARIA attributes

Example Component Patterns

Animated Card with Hover Delight

<script lang="ts">
  import { fly, scale } from 'svelte/​transition'
  import { cubicOut, elasticOut } from 'svelte/​easing'

  let isHovered = $state(false)

  interface Props {
    title: string
    description: string
    image?: string
  }

  let { title, description, image }: Props = $props()
</​script>

<article
  in:fly={{ y: 40, duration: 500, easing: cubicOut }}
  class="card"
  on:mouseenter={() => (isHovered = true)}
  on:mouseleave={() => (isHovered = false)}
>
  {#if image}
    <img src={image} alt="" class="card-image" />
  {/​if}

  <div class="card-content">
    <h3>{title}</​h3>
    <p>{description}</​p>

    {#if isHovered}
      <button
        in:scale={{ start: 0.8, duration: 300, easing: elasticOut }}
        class="card-action"
      >
        Learn More
      </​button>
    {/​if}
  </​div>
</​article>

<style>
  .card {
    background: var(--color-bg);
    border-radius: 12px;
    overflow: hidden;
    transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
    cursor: pointer;
  }

  .card:hover {
    transform: translateY(-12px);
    box-shadow: 0 24px 48px rgba(0, 0, 0, 0.15);
  }

  .card-image {
    width: 100%;
    height: 240px;
    object-fit: cover;
  }

  .card-content {
    padding: calc(var(--spacing-unit) * 3);
  }

  h3 {
    font-family: var(--font-display);
    font-size: var(--size-h2);
    font-weight: 700;
    margin: 0 0 calc(var(--spacing-unit) * 2) 0;
    color: var(--color-text);
  }

  p {
    font-family: var(--font-body);
    font-size: var(--size-body);
    line-height: 1.6;
    color: rgba(0, 0, 0, 0.7);
    margin: 0;
  }

  .card-action {
    margin-top: calc(var(--spacing-unit) * 2);
    padding: calc(var(--spacing-unit) * 1.5) calc(var(--spacing-unit) * 3);
    background: var(--color-accent);
    color: white;
    border: none;
    border-radius: 6px;
    font-family: var(--font-body);
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease-out;
  }

  .card-action:hover {
    background: var(--color-accent-dark);
    transform: scale(1.05);
  }
</​style>

Staggered List Animation

<script lang="ts">
  import { slide } from 'svelte/​transition'
  import { cubicOut } from 'svelte/​easing'

  interface ListItem {
    id: string
    label: string
  }

  interface Props {
    items: ListItem[]
  }

  let { items }: Props = $props()
</​script>

<ul class="list">
  {#each items as item, index (item.id)}
    <li
      in:slide={{
        duration: 400,
        delay: index * 50,
        easing: cubicOut,
      }}
      out:slide={{ duration: 200 }}
    >
      <span class="list-number">{index + 1}</​span>
      <span class="list-label">{item.label}</​span>
    </​li>
  {/​each}
</​ul>

<style>
  .list {
    list-style: none;
    padding: 0;
    margin: 0;
  }

  li {
    display: flex;
    align-items: center;
    padding: calc(var(--spacing-unit) * 2) calc(var(--spacing-unit) * 3);
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
    transition: background-color 0.3s ease-out;
  }

  li:hover {
    background-color: rgba(0, 0, 0, 0.02);
  }

  .list-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    margin-right: calc(var(--spacing-unit) * 2);
    background: var(--color-accent);
    color: white;
    border-radius: 50%;
    font-weight: 600;
    font-size: 13px;
  }

  .list-label {
    font-family: var(--font-body);
    font-size: var(--size-body);
    color: var(--color-text);
  }
</​style>

Svelte-Specific Best Practices

  1. Type Safety: Always use TypeScript in component scripts
  2. Reactivity: Leverage $derived for computed values and $effect for side effects
  3. Transitions: Use built-in svelte/​transition for all animations
  4. Scoped Styles: Rely on Svelte's default scoped styling; use :global() sparingly
  5. CSS Variables: Store design tokens as CSS variables for dynamic theming
  6. Stores: Use writable for theme, animation state, and global UI state
  7. Accessibility: Always include semantic HTML, ARIA labels, and proper focus management
  8. Performance: Use bind: carefully, memoize expensive computations with $derived

Resources & References


Ready to build distinctive, intentional Svelte frontends? Start with Phase 1: Design Thinking & Intent Definition. Never skip the pre-coding work.

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View