library-picturebook-activity/.claude/skills/design-system/SKILL.md
2026-01-16 14:48:14 +08:00

463 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: design-system
description: "比赛管理系统设计规范。当用户提出页面开发需求时自动应用。主色: #0958d9 蓝色主题。包含: 颜色系统、间距、圆角、阴影、字体、组件规范(按钮、卡片、表单、标签)、页面布局、动画效果。适用: 新增页面、修改样式、组件开发、UI调整。"
---
# 比赛管理系统 - 设计规范 Skill
当用户提出页面开发、UI修改、组件创建等需求时**必须遵循以下设计规范**。
---
## 快速开始
每个新页面的 `<style scoped lang="scss">` 开头必须包含以下变量:
```scss
// ==========================================
// 项目统一设计变量 - 必须复制
// ==========================================
$primary: #1890ff;
$primary-dark: #0958d9;
$primary-light: #40a9ff;
$secondary: #4096ff;
$success: #52c41a;
$warning: #faad14;
$error: #ff4d4f;
$background: #f5f7fa;
$surface: #ffffff;
$text: rgba(0, 0, 0, 0.85);
$text-secondary: rgba(0, 0, 0, 0.65);
$text-muted: rgba(0, 0, 0, 0.45);
$border: #d9d9d9;
$border-light: #e8e8e8;
$gradient-primary: linear-gradient(135deg, $primary 0%, $primary-dark 100%);
```
---
## 色彩系统
### 主色(蓝色主题)
| 变量 | 色值 | 用途 |
|------|------|------|
| `$primary` | `#1890ff` | 主色、按钮、链接 |
| `$primary-dark` | `#0958d9` | 渐变深色、激活态 |
| `$primary-light` | `#40a9ff` | 悬停态、浅色 |
| `$secondary` | `#4096ff` | 辅助蓝 |
### 功能色
| 变量 | 色值 | 用途 |
|------|------|------|
| `$success` | `#52c41a` | 成功状态 |
| `$warning` | `#faad14` | 警告状态 |
| `$error` | `#ff4d4f` | 错误状态 |
### 中性色
| 变量 | 色值 | 用途 |
|------|------|------|
| `$background` | `#f5f5f5` | 页面背景 |
| `$surface` | `#ffffff` | 卡片/容器背景 |
| `$text` | `rgba(0,0,0,0.85)` | 主文本 |
| `$text-secondary` | `rgba(0,0,0,0.65)` | 次要文本 |
| `$text-muted` | `rgba(0,0,0,0.45)` | 弱化文本 |
| `$border-light` | `#e8e8e8` | 边框 |
---
## 间距规范
基于 **8px** 基准:
| 尺寸 | 值 | 场景 |
|------|------|------|
| xs | 4px | 图标间距 |
| sm | 8px | 元素内间距 |
| md | 12px | 卡片内元素 |
| base | 16px | 最常用 |
| lg | 20px | 区块间距 |
| xl | 24px | 大间距 |
| 2xl | 32px | 模块分隔 |
---
## 圆角规范
| 尺寸 | 值 | 场景 |
|------|------|------|
| sm | 4px | 小元素 |
| base | 6px | 默认 |
| md | 8px | 卡片 |
| lg | 10px | 返回按钮 |
| xl | 12px | 大卡片 |
| pill | 20px | 标签 |
| full | 50% | 头像 |
---
## 阴影规范
| 等级 | 定义 | 场景 |
|------|------|------|
| sm | `0 1px 2px rgba(0,0,0,0.03)` | 轻微 |
| base | `0 2px 8px rgba(0,0,0,0.06)` | 卡片默认 |
| md | `0 4px 12px rgba(0,0,0,0.08)` | 悬停 |
| lg | `0 8px 24px rgba(0,0,0,0.12)` | 弹窗 |
---
## 字体规范
| 层级 | 大小 | 权重 | 场景 |
|------|------|------|------|
| h1 | 36px | 700 | 大标题 |
| h2 | 26px | 700 | 区块标题 |
| h3 | 22px | 600 | 卡片标题 |
| h4 | 18px | 600 | 小标题 |
| body | 14px | 400 | 正文 |
| small | 12px | 400 | 标签 |
---
## 组件规范
### 返回按钮(统一样式)
```scss
.back-btn {
width: 40px;
height: 40px;
border-radius: 10px !important;
border: 1px solid rgba($primary, 0.3) !important;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease !important;
&:hover {
background: rgba($primary, 0.1) !important;
border-color: $primary !important;
transform: translateY(-1px);
}
}
```
模板代码:
```vue
<a-button type="text" class="back-btn" @click="handleBack">
<template #icon><ArrowLeftOutlined /></template>
</a-button>
```
### 主按钮(渐变样式)
```scss
.primary-btn,
.gradient-btn {
background: linear-gradient(135deg, $primary 0%, $primary-dark 100%) !important;
border: none !important;
color: #fff !important;
font-weight: 500 !important;
border-radius: 20px !important;
padding: 6px 16px !important;
transition: all 0.3s ease !important;
box-shadow: 0 2px 8px rgba($primary, 0.3);
&:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba($primary, 0.4);
}
}
// 用于 hero 区域的大按钮
.action-btn.primary {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 12px 28px;
border-radius: 24px;
font-size: 15px;
font-weight: 600;
background: linear-gradient(135deg, $primary 0%, $primary-dark 100%);
color: #fff;
border: none;
cursor: pointer;
box-shadow: 0 4px 15px rgba($primary, 0.4);
transition: all 0.3s;
&:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba($primary, 0.5);
}
}
```
### 卡片
```scss
.card {
background: $surface;
border: 1px solid $border-light;
border-radius: 8px;
padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
transition: all 0.3s ease;
&:hover {
border-color: rgba($primary, 0.3);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
transform: translateY(-4px);
}
}
```
### 标签
```scss
.tag {
display: inline-flex;
align-items: center;
padding: 4px 12px;
border-radius: 20px;
font-size: 12px;
font-weight: 600;
&.tag-success {
background: rgba($success, 0.1);
color: $success;
border: 1px solid rgba($success, 0.3);
}
&.tag-primary {
background: rgba($primary, 0.1);
color: $primary;
border: 1px solid rgba($primary, 0.3);
}
&.tag-error {
background: rgba($error, 0.1);
color: $error;
border: 1px solid rgba($error, 0.3);
}
}
```
### 面板/浮层
```scss
.panel {
background: rgba($surface, 0.85);
backdrop-filter: blur(20px);
border: 1px solid rgba($primary, 0.2);
border-radius: 12px;
.panel-header {
padding: 14px 16px;
background: rgba($primary, 0.05);
border-bottom: 1px solid rgba($primary, 0.1);
}
.panel-body {
padding: 16px;
}
}
```
---
## 页面布局规范
### 页面头部64px 高)
```scss
.page-header {
height: 64px;
padding: 0 24px;
display: flex;
align-items: center;
justify-content: space-between;
background: $surface;
border-bottom: 1px solid #e8e8e8;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
position: relative;
z-index: 10;
.header-left {
display: flex;
align-items: center;
gap: 16px;
}
.title {
font-size: 18px;
font-weight: 600;
background: $gradient-primary;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
}
```
### 全屏页面容器
```scss
.fullscreen-page {
min-height: 100vh;
background: $background;
display: flex;
flex-direction: column;
position: relative;
overflow: hidden;
}
.page-content {
flex: 1;
padding: 24px;
overflow: auto;
}
```
### 卡片网格
```scss
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 20px;
}
```
---
## 动画规范
### 过渡时间
- 标准过渡:`0.3s ease`
- 所有交互元素必须添加过渡
### 悬停效果
```scss
// 卡片悬停
transform: translateY(-4px);
// 按钮悬停
transform: translateY(-2px);
// 小元素悬停
transform: translateY(-1px);
```
### 常用动画
```scss
// 脉冲
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.5; transform: scale(0.8); }
}
// 旋转
@keyframes spin {
to { transform: rotate(360deg); }
}
```
---
## 加载/错误状态
### 加载遮罩
```scss
.loading-overlay {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: $background;
z-index: 10;
}
```
### 错误卡片
```scss
.error-card {
text-align: center;
padding: 40px;
background: $surface;
border: 1px solid #e8e8e8;
border-radius: 16px;
.error-icon {
width: 60px;
height: 60px;
margin: 0 auto 20px;
background: $error;
border-radius: 50%;
color: #fff;
}
}
```
---
## 滚动条
```scss
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track {
background: rgba($primary, 0.05);
}
&::-webkit-scrollbar-thumb {
background: rgba($primary, 0.3);
border-radius: 3px;
}
```
---
## 响应式断点
```scss
$breakpoint-sm: 640px;
$breakpoint-md: 768px;
$breakpoint-lg: 1024px;
$breakpoint-xl: 1280px;
```
---
## 开发检查清单
新增页面必须确认:
- [ ] 复制了颜色变量到 style 开头
- [ ] 返回按钮使用 40x40px + 10px 圆角
- [ ] 卡片悬停有 `translateY(-4px)` 效果
- [ ] 页面头部高度 64px
- [ ] 所有过渡动画 0.3s
- [ ] 使用 `$gradient-primary` 作为主渐变
- [ ] 加载状态使用蓝色系
---
## 参考页面
- `frontend/src/views/workbench/ai-3d/Index.vue` - 3D Lab 主页
- `frontend/src/views/workbench/ai-3d/Generate.vue` - 生成页
- `frontend/src/views/model/ModelViewer.vue` - 模型预览页