AgentSkillsCN

clean-web-design

以专业设计系统为基础,运用 HSL CSS 自定义属性、Tailwind CSS 工具类、明暗模式支持,以及受 shadcn/ui 启发的组件架构,打造简洁而现代的 Web 前端界面。无论您是在构建 Web UI、React 组件、仪表板、着陆页、Web 应用,还是任何需要呈现精致、专业的前端界面时,都可使用此技能。当用户提到希望拥有“简洁”或“现代”的设计、要求支持暗黑模式,或需要为自己的 Web 项目打造一套统一的设计系统时,同样适用。本技能涵盖字体排版、色彩变量、间距规范、组件样式(卡片、按钮、输入框、模态框、导航栏)、布局结构、数据可视化主题、加载状态,以及响应式设计。

SKILL.md
--- frontmatter
name: clean-web-design
description: "Guide for building clean, modern web front-ends with a professional design system featuring HSL CSS custom properties, Tailwind CSS utility classes, light/dark mode support, and shadcn/ui-inspired component architecture. Use this skill whenever building a web UI, React component, dashboard, landing page, web app, or any front-end that should look polished and professional. Also use when the user mentions wanting a 'clean' or 'modern' design, asks for dark mode support, or needs a consistent design system for their web project. This skill covers typography, color tokens, spacing, component patterns (cards, buttons, inputs, modals, navigation), layout structure, data visualization theming, loading states, and responsive design."

Clean Web Design System

This skill captures a professional, minimal design aesthetic for web front-ends. The style is characterized by restrained use of color, generous whitespace, crisp typography, and seamless light/dark mode transitions — the kind of design you'd see in a well-crafted SaaS dashboard or modern productivity tool.

The system is built on three pillars:

  1. HSL CSS custom properties as a semantic color token layer
  2. Tailwind CSS for utility-first styling
  3. Component composition with small, reusable UI primitives (shadcn/ui style)

Read references/design-tokens.md for the complete color token system and CSS/Tailwind setup. Read references/component-patterns.md for copy-pasteable component code.

Philosophy

Every pixel of border, shadow, and color should serve a purpose. The palette is intentionally narrow — mostly neutrals with a single primary accent — so the user's content takes center stage. Dark mode is a first-class citizen achieved by swapping CSS custom property values, not by overriding individual styles.

If something doesn't need to be colorful, it shouldn't be. Text is the primary communicator. Color is reserved for status indicators (green = good, red = bad, amber = caution) and interactive affordances (primary buttons, active nav items, focus rings).

Tech Stack

The design system is framework-flexible but optimized for:

  • React with TypeScript
  • Tailwind CSS with darkMode: ['class']
  • Lucide React for icons (16×16 at h-4 w-4 default)
  • clsx + tailwind-merge via a cn() utility for conditional class merging
  • Radix UI for accessible unstyled primitives (dialogs, dropdowns)
  • D3.js or Recharts for data visualization

For other frameworks (Vue, Svelte, plain HTML), adapt the patterns but keep the same visual language. The color tokens, spacing, and typography choices transfer directly.

Color System

Colors are HSL values (without the hsl() wrapper) in CSS custom properties on :root and .dark. This lets Tailwind apply opacity modifiers like bg-primary/10.

There's no "blue-500" or "gray-300" here. Every color has a semantic name describing its purpose. This makes dark mode trivial — swap the variable values and every component updates automatically.

Core Tokens

TokenPurposeLightDark
--backgroundPage backgroundwhitenear-black navy
--foregroundPrimary textnear-black navynear-white
--card / --card-foregroundCard surfaces & textwhite / darkdark / light
--primary / --primary-foregroundPrimary actions, emphasisdark navy / near-whitenear-white / dark navy
--secondary / --secondary-foregroundSecondary surfacespale blue-gray / darkdark blue-gray / light
--muted / --muted-foregroundMuted backgrounds, subdued textpale / medium graydark / lighter gray
--accent / --accent-foregroundHover states, active navpale / darkdark / light
--destructive / --destructive-foregroundError, dangerred / whitemuted red / white
--borderAll borderslight graydark blue-gray
--inputInput borderslight graydark blue-gray
--ringFocus ringsdark navylight gray
--radiusBorder radius base0.5rem0.5rem

See references/design-tokens.md for exact HSL values and the full CSS setup.

Status Colors

For semantic indicators outside the token system, use Tailwind colors with dark variants:

  • Success: text-green-600 bg-green-100 / dark:text-green-400 dark:bg-green-900
  • Error: text-red-600 bg-red-100 / dark:text-red-400 dark:bg-red-900
  • Warning: text-amber-600 bg-amber-100 / dark:text-amber-400 dark:bg-amber-900
  • Info: text-blue-600 bg-blue-100 / dark:text-blue-400 dark:bg-blue-900

Badge pattern: bg-{color}-100 text-{color}-800 dark:bg-{color}-900 dark:text-{color}-200

Typography

System font stack (no custom fonts — keeps things fast and native-feeling).

ElementClassesWhen to use
Page titletext-3xl font-bold tracking-tightTop of each page
Page subtitletext-muted-foregroundBelow page title
Card/section titletext-2xl font-semibold leading-none tracking-tightCardTitle component
Subsection headertext-lg font-semiboldDetail panel headers
Section labeltext-base font-mediumSmaller headings
Body texttext-smDefault content size
Small/metadatatext-xs text-muted-foregroundLabels, timestamps, captions
KPI / hero numbertext-2xl font-boldStatistics, large values

Key rules: body text is always text-sm. Metadata and secondary info is always text-xs text-muted-foreground. Statistics are text-2xl font-bold. Small section labels within cards pair an icon with text-xs text-muted-foreground.

Spacing & Layout

Page Structure

code
Sidebar (fixed w-64, border-r, bg-card) | Main (pl-64, p-8 inner)
                                         | └─ space-y-6 between sections

Grid Patterns

  • KPI cards: grid gap-4 md:grid-cols-2 lg:grid-cols-4
  • Content grid: grid gap-4 md:grid-cols-2 lg:grid-cols-3
  • Stat row in card: grid grid-cols-3 gap-4
  • Card directory: grid gap-4 md:grid-cols-2 lg:grid-cols-3

Spacing Scale

  • Card padding: p-6 (standard) / p-4 (compact)
  • Between sections: space-y-6
  • Between items in list: space-y-2 or space-y-3
  • Icon-to-label gap: gap-1.5 (tight) / gap-2 (normal) / gap-3 (spacious)
  • Tag wrapping: flex flex-wrap gap-1.5
  • Filter chips: gap-3

Components

See references/component-patterns.md for full component code. Quick reference:

Cards

The foundational surface — everything lives in a card.

  • Base: rounded-lg border bg-card text-card-foreground shadow-sm
  • Interactive: add hover:bg-muted/50 transition-colors cursor-pointer
  • Structure: Card > CardHeader > CardTitle + CardDescription > CardContent > CardFooter

Buttons

Six variants (default, destructive, outline, secondary, ghost, link) × four sizes (default, sm, lg, icon). Icons: h-4 w-4 mr-2 before text.

Inputs

h-10 rounded-md border border-input bg-background px-3 py-2 text-sm with focus ring and disabled states. Labels: block text-sm font-medium mb-2. Help text: text-xs text-muted-foreground mt-1.

Navigation

Sidebar items: flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors. Active: bg-accent text-accent-foreground. Inactive: text-muted-foreground hover:bg-accent hover:text-accent-foreground.

Badges & Pills

  • Status: inline-flex items-center gap-1 text-xs px-2 py-0.5 rounded
  • Topic: text-xs bg-secondary px-2 py-1 rounded-full
  • Tag: text-xs bg-primary/10 text-primary px-2 py-1 rounded-full

Avatars (Initials)

flex items-center justify-center shrink-0 rounded-full bg-primary/10 font-medium Sizes: h-6 w-6 text-xs / h-8 w-8 text-sm / h-10 w-10 text-sm / h-14 w-14 text-lg

Loading States

  • Skeleton: bg-muted animate-pulse rounded (sized to match content)
  • Spinner: animate-spin rounded-full h-8 w-8 border-b-2 border-primary
  • Inline: text-muted-foreground with "Loading..." text

Empty States

flex items-center justify-center h-32 text-muted-foreground with a simple message.

Error States

Container: rounded-lg border border-destructive/50 bg-destructive/10 p-4, text: text-sm text-destructive

Data Visualization

Charts use the CSS custom properties for automatic theme integration:

  • Line/area stroke: hsl(var(--primary))
  • Area fill: hsl(var(--primary) / 0.2)
  • Bar fill: hsl(var(--primary)), hover: hsl(var(--primary) / 0.8)
  • Bar corners: rx: 4
  • Axis text: CSS class fill-muted-foreground text-xs
  • Grid lines: stroke: currentColor, stroke-opacity: 0.1
  • Tooltips: background: hsl(var(--popover)), color: hsl(var(--popover-foreground)), border: 1px solid hsl(var(--border)), border-radius: 6px, padding: 8px 12px, font-size: 12px, box-shadow: 0 2px 8px rgba(0,0,0,0.1)
  • Sparkline bars: flex items-end gap-1 h-8, each bar flex-1 bg-primary/20 rounded-t

Dark Mode Implementation

Toggle via .dark class on <html> using Tailwind's darkMode: ['class']. Store preference in localStorage. Toggle button in sidebar header using Moon/Sun lucide icons.

Use the dark: prefix only for colors outside the token system (status colors). For everything else — backgrounds, text, borders, cards, inputs — semantic token classes handle it automatically.

Accessibility

  • Focus rings: focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2
  • Semantic HTML: <nav>, <main>, <aside>, <button>, proper heading hierarchy
  • Screen reader text: <span className="sr-only"> for icon-only buttons
  • Aria labels on icon buttons
  • Disabled: disabled:pointer-events-none disabled:opacity-50

Transitions

Keep animations subtle: transition-colors on hover states, animate-pulse for skeletons, animate-spin for spinners, duration-200 for modals. No flashy animations — the interface should feel responsive, not performative.