ui-design
npx skills add https://github.com/petrilahdelma/digitaltableteur --skill ui-design
Agent 安装分布
Skill 文档
UI Design Expert
Core UI Design Principles
When designing user interfaces, always follow these principles:
- Visual Hierarchy: Guide attention through size, weight, color, contrast
- Consistency: Use systematic patterns for predictability
- White Space: Breathing room improves comprehension
- Contrast: Ensure readability and focus
- Alignment: Create order and visual connections
- Repetition: Reinforce brand and structure
Design System Foundation
Design Tokens (Variables)
Purpose: Single source of truth for design decisions
Token Categories:
/* Color Tokens */
--color-primary: #0066cc;
--color-secondary: #6c757d;
--color-success: #28a745;
--color-warning: #ffc107;
--color-danger: #dc3545;
--color-text: #212529;
--color-background: #ffffff;
/* Spacing Scale (8px base) */
--space-2: 0.125rem; /* 2px */
--space-4: 0.25rem; /* 4px */
--space-8: 0.5rem; /* 8px */
--space-12: 0.75rem; /* 12px */
--space-16: 1rem; /* 16px */
--space-24: 1.5rem; /* 24px */
--space-32: 2rem; /* 32px */
--space-48: 3rem; /* 48px */
--space-64: 4rem; /* 64px */
/* Typography Scale (Modular 1.25 ratio) */
--font-size-xs: 0.75rem; /* 12px */
--font-size-sm: 0.875rem; /* 14px */
--font-size-base: 1rem; /* 16px */
--font-size-lg: 1.25rem; /* 20px */
--font-size-xl: 1.5rem; /* 24px */
--font-size-2xl: 2rem; /* 32px */
--font-size-3xl: 2.5rem; /* 40px */
--font-size-4xl: 3rem; /* 48px */
--font-size-display: clamp(5rem, 10vw + 3rem, 8rem); /* 80-128px */
/* Font Weights */
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
/* Line Heights */
--line-height-tight: 1.2;
--line-height-normal: 1.5;
--line-height-relaxed: 1.75;
/* Border Radius */
--radius-sm: 0.25rem; /* 4px */
--radius-md: 0.5rem; /* 8px */
--radius-lg: 1rem; /* 16px */
--radius-full: 9999px; /* Circle */
/* Shadows */
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
/* Z-Index Scale */
--z-dropdown: 1000;
--z-sticky: 1020;
--z-fixed: 1030;
--z-modal-backdrop: 1040;
--z-modal: 1050;
--z-popover: 1060;
--z-tooltip: 1070;
Color System
Color Theory for UI
60-30-10 Rule:
- 60%: Dominant color (backgrounds, large areas)
- 30%: Secondary color (sections, panels)
- 10%: Accent color (CTAs, highlights)
Semantic Color Palette
Primary (Brand):
âââ primary-50: #e6f2ff (lightest - backgrounds)
âââ primary-100: #b3d9ff
âââ primary-200: #80c0ff
âââ primary-300: #4da7ff
âââ primary-400: #1a8eff
âââ primary-500: #0066cc â Base
âââ primary-600: #0052a3
âââ primary-700: #003d7a
âââ primary-800: #002952
âââ primary-900: #001429 (darkest - text on light bg)
Success (Green):
âââ Positive actions
âââ Confirmation states
âââ Valid inputs
Warning (Yellow/Orange):
âââ Caution states
âââ Important notices
âââ Pending actions
Danger (Red):
âââ Destructive actions
âââ Error states
âââ Invalid inputs
Neutral (Gray):
âââ Text hierarchy
âââ Borders
âââ Disabled states
Color Accessibility (WCAG)
Contrast Ratios:
- AA Standard: 4.5:1 for normal text, 3:1 for large text (18px+)
- AAA Enhanced: 7:1 for normal text, 4.5:1 for large text
Test Colors:
# Use WebAIM Contrast Checker
https://webaim.org/resources/contrastchecker/
# Or test in code
npm install wcag-color
Example:
â
PASS: #0066cc text on #ffffff background (7.5:1)
â FAIL: #80c0ff text on #ffffff background (2.1:1)
Dark Mode Strategy
Approach: Invert semantic colors, not direct colors
/* Light Mode */
:root {
--color-background: #ffffff;
--color-surface: #f8f9fa;
--color-text: #212529;
--color-text-secondary: #6c757d;
--color-border: #dee2e6;
}
/* Dark Mode */
[data-theme="dark"] {
--color-background: #1a1a1a;
--color-surface: #2d2d2d;
--color-text: #f8f9fa;
--color-text-secondary: #adb5bd;
--color-border: #495057;
/* Reduce saturation for less eye strain */
--color-primary: #4da7ff; /* Lighter than light mode */
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.5); /* Deeper shadows */
}
Typography
Type Scale (Modular Scale)
Formula: base à ratio^n
Common Ratios:
- 1.125 (Major Second): Subtle, dense
- 1.25 (Major Third): Balanced â Recommended
- 1.333 (Perfect Fourth): Dynamic
- 1.5 (Perfect Fifth): Dramatic
Digitaltableteur Scale (1.25 ratio):
Display: 80-128px (clamp)
H1: 48px
H2: 40px
H3: 32px
H4: 24px
H5: 20px
Body: 16px
Small: 14px
Caption: 12px
Font Pairing
Recommended Combinations:
-
Serif + Sans-Serif (Classic)
- Headings: Playfair Display (serif)
- Body: Inter (sans-serif)
-
Geometric + Humanist (Modern)
- Headings: Montserrat (geometric)
- Body: Open Sans (humanist)
-
Monospace + Sans (Technical)
- Code: Fira Code (monospace)
- UI: Roboto (sans-serif)
Digitaltableteur Stack:
--font-title: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--font-mono: 'Fira Code', 'Courier New', monospace;
Typographic Hierarchy
/* Display (Hero Headlines) */
.display {
font-size: var(--font-size-display);
line-height: var(--line-height-tight);
font-weight: var(--font-weight-bold);
letter-spacing: -0.02em; /* Tighter for large sizes */
}
/* H1 (Page Title) */
h1 {
font-size: var(--font-size-4xl);
line-height: var(--line-height-tight);
font-weight: var(--font-weight-bold);
}
/* H2 (Section Title) */
h2 {
font-size: var(--font-size-3xl);
line-height: var(--line-height-normal);
font-weight: var(--font-weight-semibold);
}
/* Body (Paragraph) */
p {
font-size: var(--font-size-base);
line-height: var(--line-height-relaxed);
font-weight: var(--font-weight-normal);
max-width: 65ch; /* Optimal reading width */
}
/* Small (Caption, Meta) */
small {
font-size: var(--font-size-sm);
line-height: var(--line-height-normal);
color: var(--color-text-secondary);
}
Readability Guidelines
- Line Length: 45-75 characters (optimal: 65ch)
- Line Height: 1.5Ã font size for body text
- Paragraph Spacing: 1.5Ã line height
- Letter Spacing: -0.02em for large text, 0em for body
Layout & Spacing
Grid System
12-Column Grid (flexible):
.container {
max-width: 1200px;
margin-inline: auto;
padding-inline: var(--space-16);
}
.grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: var(--space-24);
}
/* 3-column layout */
.col-4 {
grid-column: span 4;
}
/* Responsive */
@media (max-width: 768px) {
.grid {
grid-template-columns: 1fr;
}
.col-4 {
grid-column: span 1;
}
}
Spacing System (8px Base)
Concept: All spacing uses multiples of 8px for visual consistency
2px: Micro (icon padding)
4px: Tiny (inline spacing)
8px: Small (tight elements)
12px: Compact (related items)
16px: Base (default spacing)
24px: Medium (section padding)
32px: Large (cards, panels)
48px: XL (major sections)
64px: XXL (hero sections)
Application:
/* Component Internal Spacing */
.card {
padding: var(--space-24); /* 24px */
}
/* Component External Spacing */
.card + .card {
margin-block-start: var(--space-16); /* 16px gap */
}
/* Section Spacing */
.section {
padding-block: var(--space-64); /* 64px top/bottom */
}
Whitespace Principles
Law of Proximity: Related items closer, unrelated farther
Bad Example:
âââââââââââââââ
â Title â â 8px gap
â Subtitle â â 8px gap
â Author â â 8px gap (too uniform)
â Date â
âââââââââââââââ
Good Example:
âââââââââââââââ
â Title â â 4px gap (related)
â Subtitle â â 24px gap (separate group)
â Author â â 4px gap (related)
â Date â
âââââââââââââââ
Component Visual Design
Button Anatomy
ââââââââââââââââââââââââââââââ
â [Icon] Label [Icon] â â Text: 14-16px, weight: 500-600
â â â â â
â 8px 12px 8px â â Spacing
ââââââââââââââââââââââââââââââ
â â
12px padding 12px padding
Height: 40-48px (min 44px for touch)
Border-radius: 8px
Button Hierarchy:
/* Primary (High emphasis) */
.btn-primary {
background-color: var(--color-primary);
color: white;
font-weight: 600;
box-shadow: var(--shadow-sm);
}
.btn-primary:hover {
background-color: var(--color-primary-600);
box-shadow: var(--shadow-md);
transform: translateY(-1px);
}
/* Secondary (Medium emphasis) */
.btn-secondary {
background-color: transparent;
color: var(--color-primary);
border: 2px solid var(--color-primary);
}
/* Tertiary (Low emphasis) */
.btn-tertiary {
background-color: transparent;
color: var(--color-primary);
text-decoration: underline;
}
Card Design
.card {
/* Structure */
background-color: var(--color-surface);
border-radius: var(--radius-lg);
padding: var(--space-24);
/* Depth */
box-shadow: var(--shadow-md);
/* Interaction */
transition:
transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
box-shadow 0.3s ease;
}
.card:hover {
transform: scale(1.02);
box-shadow: var(--shadow-xl);
}
/* Card Anatomy */
.card-header {
margin-block-end: var(--space-16);
}
.card-title {
font-size: var(--font-size-xl);
font-weight: var(--font-weight-semibold);
color: var(--color-text);
}
.card-content {
font-size: var(--font-size-base);
line-height: var(--line-height-relaxed);
color: var(--color-text-secondary);
}
.card-footer {
margin-block-start: var(--space-24);
padding-block-start: var(--space-16);
border-block-start: 1px solid var(--color-border);
}
Form Input Design
.input {
/* Size */
min-height: 48px;
padding: 12px 16px;
/* Typography */
font-size: var(--font-size-base);
line-height: 1.5;
/* Visual */
background-color: var(--color-background);
border: 2px solid var(--color-border);
border-radius: var(--radius-md);
/* Interaction */
transition: all 0.2s ease;
}
.input:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 4px rgba(0, 102, 204, 0.1); /* Focus ring */
}
.input:invalid {
border-color: var(--color-danger);
}
.input:disabled {
background-color: var(--color-surface);
color: var(--color-text-secondary);
cursor: not-allowed;
}
/* Label */
.label {
display: block;
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
color: var(--color-text);
margin-block-end: var(--space-8);
}
/* Helper Text */
.help-text {
font-size: var(--font-size-sm);
color: var(--color-text-secondary);
margin-block-start: var(--space-4);
}
/* Error Message */
.error-message {
font-size: var(--font-size-sm);
color: var(--color-danger);
margin-block-start: var(--space-4);
display: flex;
align-items: center;
gap: var(--space-4);
}
Iconography
Icon System Guidelines
Size Scale:
16px: Inline with text
20px: Buttons, inputs
24px: Navigation, cards
32px: Feature highlights
48px: Empty states, placeholders
Style:
- Stroke width: 2px (consistent across set)
- Corner radius: 2px (rounded, friendly)
- Grid: 24Ã24px with 2px padding
Usage:
import { MagnifyingGlass, User, XCircle } from '@phosphor-icons/react';
// Default size (24px)
<MagnifyingGlass />
// Custom size
<MagnifyingGlass size={32} weight="bold" />
// With color
<User color="var(--color-primary)" />
Accessibility:
// Decorative icon (hidden from screen readers)
<MagnifyingGlass aria-hidden="true" />
// Functional icon (needs label)
<button aria-label="Search">
<MagnifyingGlass />
</button>
Animation & Motion
Animation Principles
- Purposeful: Motion guides attention or provides feedback
- Subtle: Enhance, don’t distract (200-400ms)
- Natural: Use easing curves, not linear
- Respectful: Honor
prefers-reduced-motion
Easing Functions
/* Material Design Easing */
--ease-standard: cubic-bezier(0.4, 0.0, 0.2, 1); /* Default */
--ease-decelerate: cubic-bezier(0.0, 0.0, 0.2, 1); /* Enter screen */
--ease-accelerate: cubic-bezier(0.4, 0.0, 1, 1); /* Exit screen */
/* Elastic (playful) */
--ease-elastic: cubic-bezier(0.34, 1.56, 0.64, 1);
/* Usage */
.button {
transition: transform 0.3s var(--ease-standard);
}
.button:hover {
transform: scale(1.05);
}
Common Animations
Fade In:
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.fade-in {
animation: fadeIn 0.3s var(--ease-standard);
}
Slide Up:
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.slide-up {
animation: slideUp 0.4s var(--ease-decelerate);
}
Gradient Flow (Digitaltableteur):
@keyframes gradient-move {
0%, 100% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
}
.gradient-text {
background: linear-gradient(120deg, #667eea, #764ba2, #f093fb);
background-size: 200% 200%;
animation: gradient-move 4s ease-in-out infinite;
background-clip: text;
-webkit-text-fill-color: transparent;
}
Reduced Motion
/* Respect user preference */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
Responsive Design
Breakpoints
/* Mobile First Approach */
/* Small (mobile) - default, no media query */
.container {
padding: var(--space-16);
}
/* Medium (tablet) - 768px+ */
@media (min-width: 768px) {
.container {
padding: var(--space-24);
}
}
/* Large (desktop) - 1024px+ */
@media (min-width: 1024px) {
.container {
padding: var(--space-32);
max-width: 1200px;
}
}
/* Extra Large (wide desktop) - 1440px+ */
@media (min-width: 1440px) {
.container {
max-width: 1400px;
}
}
Fluid Typography
/* Scales smoothly between breakpoints */
h1 {
font-size: clamp(2rem, 5vw + 1rem, 4rem);
/* Min: 32px, Ideal: 5vw+16px, Max: 64px */
}
p {
font-size: clamp(1rem, 1vw + 0.75rem, 1.25rem);
/* Min: 16px, Ideal: 1vw+12px, Max: 20px */
}
Design-to-Dev Handoff (Figma)
Figma Best Practices
Layer Naming:
â
Good: button-primary-large
â Bad: Rectangle 23
Component Organization:
Components/
âââ Foundations/
â âââ Colors
â âââ Typography
â âââ Spacing
âââ Atoms/
â âââ Button
â âââ Input
â âââ Icon
âââ Molecules/
â âââ Card
â âââ Form Field
âââ Organisms/
âââ Header
âââ Footer
Auto Layout (Flexbox equivalent):
- Use for all components
- Set spacing, padding explicitly
- Configure resizing behavior
Variants (Component states):
Button:
âââ Variant: Primary, Secondary, Tertiary
âââ Size: Small, Medium, Large
âââ State: Default, Hover, Active, Disabled
âââ Icon: Left, Right, None
Handoff Checklist
- All text layers use shared text styles
- All colors reference design tokens (not hex values)
- Spacing uses 8px grid
- Components use Auto Layout
- All states documented (hover, active, disabled)
- Responsive behavior specified
- Accessibility notes added (alt text, ARIA labels)
- Interactive prototype for complex flows
- Developer mode enabled (CSS code snippets)
Visual Hierarchy Techniques
Size & Scale
Largest: Display Headlines (guide attention immediately)
â
Large: Page Titles (establish context)
â
Medium: Section Headings (organize content)
â
Base: Body Text (readable, comfortable)
â
Small: Captions, Meta (supporting info)
Weight & Contrast
Boldest: CTAs, Primary Actions (demand action)
â
Bold: Headings (structure)
â
Semibold: Subheadings, Labels (clarity)
â
Regular: Body (readability)
â
Light: De-emphasized Text (background info)
Color Emphasis
High Contrast: Black on White (critical info)
Medium Contrast: Gray on White (secondary info)
Low Contrast: Light Gray on White (tertiary info)
Accent Color: Brand Color (CTAs, highlights)
Brand Application (Digitaltableteur)
Brand Colors
--accent-pink: #ff006e;
--accent-purple: #8338ec;
--accent-cyan: #00d9ff;
--accent-teal: #06ffa5;
--accent-yellow: #ffbe0b;
--accent-violet: #7209b7;
/* Gradient (Signature) */
--home-gradient: linear-gradient(120deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
Section Accent Pattern
// Rotate accent colors for visual rhythm
<section className={styles.sectionAccentPink}>
{/* Content */}
</section>
<section className={styles.sectionAccentCyan}>
{/* Content */}
</section>
<section className={styles.sectionAccentYellow}>
{/* Content */}
</section>
Gradient Text (CTAs)
.gradientText {
background: var(--home-gradient);
background-size: 200% 200%;
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: gradient-move 4s ease-in-out infinite;
}
Micro-Interactions (Visual Feedback)
Button States
.button {
/* Idle */
background-color: var(--color-primary);
transform: scale(1);
transition: all 0.2s ease;
}
.button:hover {
/* Hover */
background-color: var(--color-primary-600);
transform: scale(1.05);
box-shadow: var(--shadow-lg);
}
.button:active {
/* Active (pressed) */
transform: scale(0.98);
box-shadow: var(--shadow-sm);
}
.button:focus-visible {
/* Focus (keyboard) */
outline: 4px solid rgba(0, 102, 204, 0.3);
outline-offset: 2px;
}
.button:disabled {
/* Disabled */
background-color: var(--color-surface);
color: var(--color-text-secondary);
cursor: not-allowed;
transform: scale(1);
}
Loading States
// Skeleton loader
<div className={styles.skeleton} />
/* CSS */
.skeleton {
background: linear-gradient(
90deg,
var(--color-surface) 0%,
var(--color-border) 50%,
var(--color-surface) 100%
);
background-size: 200% 100%;
animation: loading 1.5s ease-in-out infinite;
}
@keyframes loading {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
When to Use This Skill
Activate this skill when:
- Designing UI components or patterns
- Creating design systems or style guides
- Choosing colors, typography, or spacing
- Building visual hierarchies
- Designing for accessibility (color contrast)
- Creating design tokens or CSS variables
- Working with Figma or design tools
- Defining animation and motion
- Designing responsive layouts
- Creating brand application guidelines
- Designing micro-interactions
- Conducting design QA or reviews
- Handing off designs to developers
Remember: Consistency and accessibility are non-negotiable. Always test designs with real users and assistive technologies.