AgentSkillsCN

design-system

针对 Tailwind/JX 项目,遵循一致性原则与可复用模式,制定 UI 令牌与组件样式规范。

SKILL.md
--- frontmatter
name: design-system
description: UI tokens and component styling conventions for Tailwind/JX projects, with emphasis on consistency and reusable patterns.

Design System Skill

Use this skill when creating or changing visual language, tokens, and reusable UI components.

Scope

  • Color and semantic token usage
  • Typography, spacing, radius, shadow scales
  • Component-level visual consistency
  • Motion and interaction feedback
  • Dark/light mode behavior

Loading Order

  1. .agent/skills/design-system/ui-components.md
  2. .agent/skills/design-system/animations.md

Design System Conventions

Generic, portable design system for Tailwind CSS projects. Inspired by shadcn/ui, Basecoat UI, Preline, Tailblocks, and Common Webpage Layouts with TailwindCSS (Grid & Flexbox).

Stack: Tailwind CSS + HTMX + Alpine.js + Idiomorph

1. Color Strategy

Neutral Scale

Pick ONE neutral and use it everywhere. Recommended: Zinc.

RoleLight tokensDark tokens
Page background{neutral}-50{neutral}-950
Surface (card)white{neutral}-950
Elevated surfacewhite/80 (translucent){neutral}-950/80
Primary text{neutral}-900{neutral}-50 or 100
Secondary text{neutral}-600{neutral}-300 or 400
Muted text{neutral}-500{neutral}-400
Borders{neutral}-200{neutral}-800
Dividers{neutral}-200{neutral}-800
Hover bg{neutral}-100{neutral}-900
Disabledopacity-50opacity-50

Semantic Colors

Each semantic color follows the same pattern:

ToneColorLight bgLight textLight ringDark bgDark textDark ring
SuccessEmeraldemerald-50emerald-800emerald-200emerald-900/30emerald-200emerald-800
DangerRoserose-50rose-800rose-200rose-900/30rose-200rose-800
WarningAmberamber-50amber-800amber-200amber-900/30amber-200amber-800
InfoBlueblue-50blue-800blue-200blue-900/30blue-200blue-800
NeutralZinczinc-50zinc-700zinc-200zinc-900zinc-200zinc-700

Pattern: Dark backgrounds use {color}-900/30 (30% opacity) for subtlety.

Status Indicators

StateLightDark
OK/Upemerald-500emerald-400
Downrose-500rose-400
Warningamber-500amber-400

3. Spacing System

Base Grid: 4px

All spacing values are multiples of 4px via Tailwind's default scale.

Container Pattern

txt
max-w-{size} mx-auto w-full px-4
ContainerWidthUse
max-w-sm384pxAuth forms, small dialogs
max-w-md448pxCentered error cards
max-w-lg512pxModals
max-w-2xl672pxBlog content
max-w-4xl896pxDashboard content
max-w-6xl1152pxFull-width app layouts

Padding Conventions

ContextTokenValue
Page horizontalpx-416px
Card bodypx-5 py-420/16px
Button smpx-312px
Button mdpx-416px
Button lgpx-520px
Badgepx-2 py-0.58/2px
Navbarpy-312px
Footerpy-416px
Content areapy-624px

Gap Conventions

TokenValueUse
gap-14pxInline items (nav, icon+text)
gap-28pxButton groups, breadcrumbs
gap-312pxLogo+brand, form fields
gap-416pxCard grid items
gap-624pxPage sections
gap-832pxMajor layout sections

5. Shadows

TokenUseElevation
(none)Flat elementsGround
shadow-smCards, panelsSurface
shadow-mdToasts, floating menusFloating
shadow-lgDropdowns, popoversRaised
shadow-xlModals, overlaysOverlay
txt
Ground → Surface (sm) → Floating (md) → Raised (lg) → Overlay (xl)

7. Z-Index Layers

LayerZ-IndexElements
BaseautoPage content
Dropdownz-10Dropdowns, popovers
Stickyz-30Sticky sidebars
Navbarz-40Fixed/sticky navbar
Overlayz-50Modals, toasts, drawers

9. Dark Mode

Implementation

txt
Method:   Tailwind class-based (darkMode: 'class')
Storage:  localStorage key "theme" → "dark" | "light"
Default:  prefers-color-scheme media query fallback
Toggle:   Alpine.js x-data on <body>, $watch syncs to <html>

Inversion Rules

ElementLight → Dark transformation
Page bg{neutral}-50{neutral}-950
Surface bgwhite{neutral}-950
Translucent bgwhite/80{neutral}-950/80
Primary button{neutral}-900 bg → {neutral}-50 bg
Semantic bg{color}-50{color}-900/30
Borders{neutral}-200{neutral}-800
Primary text{neutral}-900{neutral}-50
Hover bg{neutral}-100{neutral}-900

11. Layout Patterns

Page Grid

bash
┌──────────────────────────────────────┐
│ Navbar (sticky, z-40, backdrop-blur) │
├──────────────────────────────────────┤
│ Content (flex-1, max-w-{size} px-4)  │
│  ┌──────────────────────────────┐    │
│  │  Breadcrumb (optional)       │    │
│  │  Page section (grid gap-6)   │    │
│  │    ┌──────────────────┐      │    │
│  │    │ Card / Content   │      │    │
│  │    └──────────────────┘      │    │
│  └──────────────────────────────┘    │
├──────────────────────────────────────┤
│ Footer (border-t)                    │
└──────────────────────────────────────┘

Navbar

text
sticky top-0 z-40 border-b bg-{surface}/80 backdrop-blur-lg
  └─ max-w-{size} mx-auto px-4
       ├─ Brand (logo/initial + name)
       ├─ Nav links (gap-1, rounded-md hover)
       └─ Actions (theme toggle, user menu)

Body Structure

html
<body class="flex min-h-screen flex-col bg-{neutral}-50 dark:bg-{neutral}-950">
  <header>Navbar</header>
  <main class="w-full flex-1">Content</main>
  <footer>Footer</footer>
  <div id="modal-portal"></div>
  <div id="toast-portal"></div>
</body>

Common Responsive Layouts

Use CSS Grid for page-level layout, Flexbox for component-level alignment.

One-Column (Header + Content + Footer)

html
<div class="flex min-h-screen flex-col">
  <header class="bg-blue-500 p-4">Header</header>
  <main class="flex-grow p-4">Content</main>
  <footer class="bg-gray-300 p-4">Footer</footer>
</div>

Two-Column (Content + Right Sidebar)

html
<div class="flex min-h-screen flex-col">
  <header class="bg-blue-500 p-4">Header</header>
  <div class="flex flex-grow flex-col md:flex-row">
    <main class="order-2 flex-grow p-4 md:order-1">Content</main>
    <aside class="order-1 w-full bg-gray-200 p-4 md:order-2 md:w-64">Sidebar</aside>
  </div>
  <footer class="bg-gray-300 p-4">Footer</footer>
</div>

Two-Column (Left Sidebar + Content)

html
<div class="flex min-h-screen flex-col">
  <header class="bg-blue-500 p-4">Header</header>
  <div class="flex flex-grow flex-row">
    <aside class="hidden w-64 bg-gray-200 p-4 sm:block">Sidebar</aside>
    <main class="flex-grow p-4">Content</main>
  </div>
  <footer class="bg-gray-300 p-4">Footer</footer>
</div>

Three-Column (Left Sidebar + Content + Right Sidebar)

html
<div class="grid min-h-screen grid-cols-1 grid-rows-[auto,1fr,auto] md:grid-cols-[200px,1fr] lg:grid-cols-[200px,1fr,200px]">
  <header class="col-span-full bg-blue-500 p-4">Header</header>
  <aside class="hidden bg-gray-200 p-4 md:row-start-2 md:block">Left Sidebar</aside>
  <main class="row-start-2 bg-white p-4 md:col-start-2">Content</main>
  <aside class="hidden bg-gray-200 p-4 lg:row-start-2 lg:block">Right Sidebar</aside>
  <footer class="col-span-full bg-gray-300 p-4">Footer</footer>
</div>

Dashboard (Collapsible Sidebar)

css
grid-template-areas:
  'nav header header'
  'nav content sidebar'
  'nav footer footer';

Ideal for admin panels. Sidebar collapses on mobile via responsive grid columns.

Layout Decision Tree

txt
Single content column?          → Flexbox (flex-col min-h-screen)
Content + sidebar?              → Flexbox (flex-row on md+, stacked on mobile)
Content + 2 sidebars?           → CSS Grid (grid-cols responsive breakpoints)
Dashboard with collapsible nav? → CSS Grid (grid-template-areas)

13. Alpine.js State Patterns

Patternx-dataBehavior
Dark mode{ dark: false }$watch syncs to html class + localStorage
Modal{ open: true }Escape/backdrop close, x-effect remove
Toast{ show: true }setTimeout auto-dismiss
Accordion{ open: false }Toggle content, cleanup on close
Dropdown{ open: false }Click-away close via @click.outside
Tabs{ tab: 'first' }Show/hide panels, :class binding

SSE Lifecycle Pattern

text
User action  → connect()    → new EventSource(url)
                              → onmessage: update state
                              → onerror: disconnect()
User action  → disconnect() → es.close(), es = null
Page leaving → disconnect() → cleanup before DOM replace

Token Presets (Merged)

Design System

Color Palette

Dark Theme (default)

TokenValueUsage
--bg#0b0b0dPage background
--surface#121215Card/panel backgrounds
--surface-2#1a1a1fElevated surfaces
--text#edededPrimary text
--text-2#a1a1aaSecondary text
--text-3#6b7280Muted/placeholder text
--border#1f1f26Borders, dividers
--accent#7c7cffPrimary accent (links)
--accent-2#22c55eSecondary accent (success)
--warn#f59e0bWarnings
--danger#ef4444Errors, destructive

Light Theme

TokenValue
--bg#fafafa
--surface#ffffff
--surface-2#f4f4f5
--text#0f172a
--accent#4f46e5

CSS implementation (tokens.css)

css
:root {
  /* Dark theme (default) */
  --bg: #0b0b0d;
  --surface: #121215;
  --surface-2: #1a1a1f;
  --text: #ededed;
  --text-2: #a1a1aa;
  --text-3: #6b7280;
  --border: #1f1f26;
  --accent: #7c7cff;
  --accent-2: #22c55e;
  --warn: #f59e0b;
  --danger: #ef4444;
}

[data-theme="light"] {
  --bg: #fafafa;
  --surface: #ffffff;
  --surface-2: #f4f4f5;
  --text: #0f172a;
  --text-2: #71717a;
  --text-3: #a1a1aa;
  --border: #e4e4e7;
  --accent: #4f46e5;
}

Spacing Scale

TokenValue
--space-10.25rem
--space-20.5rem
--space-30.75rem
--space-41rem
--space-51.5rem
--space-62rem

Shadows

TokenValue
--shadow-sm0 6px 16px rgba(0,0,0,0.18)
--shadow-md0 10px 30px rgba(0,0,0,0.22)

Guardrails

  • Use one neutral scale per project
  • Keep spacing and radius tokens consistent across components
  • Prefer semantic colors (success/warn/danger/info) over ad-hoc values
  • Ensure states (hover/focus/disabled/loading) are defined for interactive elements