xiaohongshu
xiaohongshu
frontend-design-vue
Create distinctive, production-grade Vue 3/TypeScript frontends with exceptional design quality
Full skill instructions
Create distinctive, production-grade Vue 3 frontends with TypeScript and exceptional design quality. This skill integrates the complete design system framework with Vue 3/TypeScript implementation patterns.
This skill enables you to build Vue 3 applications that avoid generic AI design patterns through:
The core 5-dimension framework for creating intentional, non-generic design that avoids the homogenized aesthetic of default AI outputs.
Purpose: Typography is the primary carrier of voice and personality in digital design.
Core Principles:
Implementation:
Example Pattern:
Purpose: Color sets mood and creates visual coherence while avoiding cliché palettes.
Core Principles:
Anti-Patterns to Avoid:
Implementation:
Example Approach:
Purpose: Motion reveals personality and guides user attention with intentionality.
Core Principles:
Implementation:
Anti-Patterns:
Purpose: Space and layout create rhythm and guide the eye through intentional composition.
Core Principles:
Implementation:
Anti-Patterns:
Purpose: The foundation layer that can transform a generic design into something memorable.
Core Principles:
Implementation:
Anti-Patterns:
Typography is the primary carrier of personality and voice in design.
Typefaces to Avoid:
If you use any of these, pair them with something unexpected and deliberately break the generic pattern.
Typefaces to Prefer:
Display & Decorative:
Body & Copy:
Monospace (Technical, Quotes, Code):
Pairing Strategy:
High-Contrast Pairings (Recommended):
Pattern 1: Display + Mono
Headline: Playfair Display (elegant serif)
Body: JetBrains Mono (technical monospace)
Result: Sophisticated + Modern
Pattern 2: Serif + Geometric Sans
Headline: Crimson Pro (high-contrast serif)
Body: Space Grotesk (geometric sans)
Result: Elegant + Contemporary
Pattern 3: Decorative + Humanist
Headline: Bricolage Grotesque (handcrafted sans)
Body: IBM Plex Sans (warm humanist sans)
Result: Crafted + Approachable
Font Weights & Extremes:
Use weight extremes to create contrast, not mid-range weights:
Good:
Avoid:
Size Jumps: Extreme Over Incremental:
Use 3x+ jumps between hierarchy levels, not incremental 1.5x steps:
Generic (Linear Scaling):
H1: 48px
H2: 36px (75% of H1)
H3: 28px (78% of H2)
Body: 16px
Small: 14px
Result: Feels predictable, every size feels similar distance apart.
Intentional (3x+ Jumps):
Display: 96px (3x body)
Headline: 48px (3x body)
Sub-headline: 28px (1.75x body)
Body: 16px
Caption: 12px (0.75x body)
Result: Creates clear visual hierarchy, extreme sizes make smaller sizes feel intentional.
Line Height & Letter Spacing:
Line Height Strategy:
Letter Spacing Strategy:
Motion reveals personality and guides user attention with intentionality.
Core Principles:
Vue Use Motion Implementation:
@vueuse/motion provides excellent Vue 3 integration for orchestrated animations:
import { useMotion } from '@vueuse/motion'
import { ref } from 'vue'
const target = ref()
useMotion(target, {
initial: { opacity: 0, y: 100 },
enter: {
opacity: 1,
y: 0,
transition: {
type: 'spring',
stiffness: 100,
delay: 100
}
}
})
Page Load Animation Strategy:
Orchestrated Reveal - Don't animate everything at once. Create a sequence that guides the user's eye:
Timing Sequence:
0ms - Background/Hero fades in
200ms - Headline slides in from top
400ms - Sub-headline fades in
600ms - Primary CTA appears
800ms - Supporting content staggered reveal
Staggered Reveals:
Using staggerChildren with @vueuse/motion:
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
delayChildren: 0.2,
},
},
};
const itemVariants = {
hidden: { opacity: 0, x: -20 },
visible: {
opacity: 1,
x: 0,
transition: { duration: 0.6 },
},
};
Scroll Trigger Animations:
Using Intersection Observer with Vue:
import { ref, onMounted } from 'vue'
const elementRef = ref()
onMounted(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-in')
observer.unobserve(entry.target)
}
})
})
if (elementRef.value) {
observer.observe(elementRef.value)
}
})
Hover State Surprises:
Hover interactions should be delightful, not just functional:
<script setup lang="ts">
import { useMotion } from '@vueuse/motion'
import { ref } from 'vue'
const card = ref()
useMotion(card, {
initial: { y: 0 },
hover: {
y: -8,
transition: {
type: 'spring',
stiffness: 200,
damping: 20
}
}
})
</script>
<template>
<div ref="card" class="card">
<!-- Content -->
</div>
</template>
Easing Functions:
Recommended Easing Values:
Anti-Patterns to Avoid:
These are the predictable defaults that appear in generic AI-generated design.
Typography Anti-Patterns:
Color & Theme Anti-Patterns:
Layout & Spatial Anti-Patterns:
Motion & Animation Anti-Patterns:
Background & Visual Details Anti-Patterns:
Checklist: Have You Avoided These?:
Before writing code or generating design, establish the intentional foundation.
The Pre-Design Checklist:
Don't design until you answer these four questions:
Purpose: Problem & Users:
Before choosing any visual element, define what you're solving:
Tone: Emotional Intent:
Based on your purpose, what emotional response should the design evoke?
Emotional Directions:
Constraints: Reality Check:
Before designing, know your boundaries:
Differentiation: The Unforgettable Element:
Every intentional design has one element that makes it memorable and distinctly yours.
Types of Differentiation:
Always use Composition API with <script setup> and TypeScript for type safety and clarity:
<script setup lang="ts">
import { ref, computed } from 'vue'
interface Props {
title: string
items: string[]
}
const props = withDefaults(defineProps<Props>(), {
items: () => []
})
const count = ref<number>(0)
const doubled = computed<number>(() => count.value * 2)
const increment = (): void => {
count.value++
}
</script>
<template>
<div class="container">
<h1>{{ title }}</h1>
<p>Count: {{ count }}</p>
<p>Doubled: {{ doubled }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<style scoped>
/* Scoped styles with CSS variables */
</style>
All Vue components should be Single File Components with semantic structure:
<script setup lang="ts">
// 1. Imports
// 2. Types & Interfaces
// 3. Props & Emits
// 4. State (ref, reactive)
// 5. Computed Properties
// 6. Methods
// 7. Watchers
// 8. Lifecycle Hooks
</script>
<template>
<!-- Semantic HTML with proper ARIA -->
</template>
<style scoped>
/* Scoped styles, CSS variables for theming */
</style>
@vueuse/motion provides composable animations that integrate seamlessly with Vue 3:
<script setup lang="ts">
import { useMotion } from '@vueuse/motion'
import { ref } from 'vue'
const target = ref()
useMotion(target, {
initial: { opacity: 0, y: 100 },
enter: {
opacity: 1,
y: 0,
transition: {
type: 'spring',
stiffness: 100,
delay: 100
}
}
})
</script>
<template>
<div ref="target" class="animated-element">
Content animates in on mount
</div>
</template>
<style scoped>
.animated-element {
will-change: opacity, transform;
}
</style>
Use CSS variables for theme management and avoid style leakage:
<style scoped>
:root {
--color-primary: #ff6b35;
--color-text: #1a1a1a;
--color-background: #fffbf7;
--spacing-base: 16px;
--font-display: 'Playfair Display', serif;
--font-body: 'IBM Plex Sans', sans-serif;
}
.component {
color: var(--color-text);
background: var(--color-background);
padding: var(--spacing-base);
font-family: var(--font-body);
}
.heading {
font-family: var(--font-display);
color: var(--color-primary);
}
</style>
Use ref() for primitives and objects, reactive() sparingly for deeply nested objects:
import { ref, reactive } from 'vue'
// For primitives and shallow objects
const count = ref<number>(0)
const name = ref<string>('Vue')
const user = ref<{ id: number; name: string }>({ id: 1, name: 'John' })
// Accessing values in script
count.value++
// For complex nested objects (use sparingly)
const state = reactive({
nested: {
deeply: {
value: 'hello'
}
}
})
// No .value needed with reactive
state.nested.deeply.value = 'world'
Use Provide/Inject to pass theme configuration down the component tree:
<!-- App.vue -->
<script setup lang="ts">
import { provide } from 'vue'
interface Theme {
primaryColor: string
secondaryColor: string
fontSize: number
}
const theme: Theme = {
primaryColor: '#ff6b35',
secondaryColor: '#004e89',
fontSize: 16
}
provide('theme', theme)
</script>
<!-- Child Component -->
<script setup lang="ts">
import { inject, computed } from 'vue'
interface Theme {
primaryColor: string
secondaryColor: string
fontSize: number
}
const theme = inject<Theme>('theme')!
const styles = computed(() => ({
color: theme.primaryColor,
fontSize: theme.fontSize + 'px'
}))
</script>
Always use semantic HTML and proper ARIA attributes:
<template>
<nav class="navbar" role="navigation" aria-label="Main navigation">
<button
class="menu-toggle"
type="button"
aria-label="Toggle menu"
:aria-expanded="menuOpen"
@click="menuOpen = !menuOpen"
>
☰
</button>
</nav>
<main id="main-content" role="main">
<h1>Page Title</h1>
<form @submit.prevent="handleSubmit">
<label for="email-input">Email Address</label>
<input
id="email-input"
v-model="email"
type="email"
placeholder="[email protected]"
aria-required="true"
aria-describedby="email-help"
>
<p id="email-help" class="help-text">We'll never share your email.</p>
</form>
<section aria-labelledby="features-heading">
<h2 id="features-heading">Features</h2>
<!-- Content -->
</section>
</main>
</template>
Always start with mobile styles and enhance for larger screens:
<style scoped>
.container {
/* Mobile: default 1 column */
display: grid;
grid-template-columns: 1fr;
gap: var(--spacing-base);
padding: var(--spacing-base);
}
/* Small devices (tablets) */
@media (min-width: 640px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
}
/* Medium devices (desktops) */
@media (min-width: 1024px) {
.container {
grid-template-columns: repeat(3, 1fr);
}
}
/* Large devices */
@media (min-width: 1280px) {
.container {
grid-template-columns: repeat(4, 1fr);
}
}
</style>
Follow these phases for consistent, intentional frontend development:
Use this checklist to ensure your Vue design is intentional, not defaulted:
<script setup>See the examples/ directory for complete Vue component examples demonstrating:
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
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...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
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...
Display project status, active tracks, and next actions
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.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience