Frontend brand
他山 Cursor Skill 体系 — 95个Skills + 32个Rules + 18个SubAgents,让AI在执行任务时能自主判断、按规范执行、并从经验中自我进化
npx -y skills add TashanGKD/tashan-cursor-skills --skill frontend-brandAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 14 stars14 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
他山前端品牌设计系统完整参考手册。包含技术框架选型、设计令牌(颜色/字体/圆角/阴影)、组件规范代码模板、响应式/无障碍约定。被 role-前端开发 和 role-UI设计师 主动调用;与 frontend-brand-guard.mdc(约束层)配套使用。
SKILL.md
28.9 KB, ~9.6k tokens by cl100k_base, as published. Nobody here has run it
他山前端品牌设计系统(frontend-brand)
关系类型:validates frontend-brand-guard.mdc / extends role-前端开发 / extends role-UI设计师
本 Skill 是可复用知识层,回答「怎么写才对」。 配套 Rule
frontend-brand-guard.mdc是约束层,回答「哪些绝对不能写」。 真相来源:所有代码以frontend/src/index.css和frontend/tailwind.config.js为准。
激活后立即执行
Step 1 明确当前场景(产品内页 or 官网/主页)
→ 不确定时默认:产品内页(黑白极简)
Step 2 定位具体需求(组件类型 / 页面类型 / 样式修改)
→ 查阅本 Skill 对应章节,直接使用规范类名和代码模板
Step 3 输出代码 / 设计方案
→ 输出前对照第十章「禁止清单」自检
Step 4 遇到本 Skill 未覆盖的细节时,按优先级查阅:
1. frontend/src/index.css(CSS 变量/动画定义的唯一真相)
2. frontend/tailwind.config.js(Tailwind 映射的唯一真相)
3. 项目群/Tashan-TopicLab/docs/design/frontend-design-guide.md(语义说明)
⚠️ 已知文档内部不一致(必须知晓)
shape-system.md 表格中写 rounded-lg = Default = 12px,但实际代码 tailwind.config.js 将 rounded-lg 映射到 var(--radius-lg) = 16px,frontend-design-guide.md 中卡片/按钮/模态框也均使用 rounded-lg。以代码为准:rounded-lg = 16px,是标准通用圆角。
一、技术框架
| 技术 | 版本 | 用途 |
|---|---|---|
| React | 18.x | UI 框架 |
| TypeScript | 5.x | 类型系统 |
| Vite | 5.x | 构建工具 |
| Tailwind CSS | 3.x | 样式(utility-first,不用 CSS-in-JS) |
| react-router-dom | 6.x | 路由 |
| react-markdown + remark-gfm | latest | Markdown 渲染 |
| KaTeX + remark-math + rehype-katex | latest | 数学公式 |
| Vitest + @testing-library/react | latest | 测试 |
样式分层:Tailwind utility → @layer components → @layer utilities(动画/工具)→ @layer base(html/body)
文件结构(实际项目):
frontend/src/
├── api/ # axios 封装
├── components/ # 可复用组件
├── hooks/ # 自定义 hooks
├── modules/ # 功能模块
├── pages/ # 页面组件
├── utils/ # 工具函数
├── App.tsx
├── main.tsx
└── index.css # CSS 变量 / @layer base / 动画 / markdown 样式
二、设计令牌(完整以代码为准)
2.1 字体
// tailwind.config.js
fontFamily: {
serif: ['Noto Serif SC', 'STSong', 'SimSun', 'serif'],
sans: ['-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'sans-serif'],
}
<!-- index.html — 字体加载 -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&display=swap" rel="stylesheet">
规则:
- 所有用户可见文字 →
font-serif(Noto Serif SC) - 技术标识/代码片段 →
font-mono - 禁止:Inter、Roboto、Arial 作主字体
2.2 排版比例(来自 frontend-design-guide.md)
| 用途 | Tailwind 类 |
|---|---|
| 页面标题 | text-xl sm:text-2xl font-serif font-bold text-black |
| 章节标题 | text-lg font-serif font-semibold text-black |
| 卡片标题 | text-base font-serif font-semibold text-black |
| 正文 | text-sm font-serif text-black 或 text-gray-600 |
| 次要信息 | text-xs text-gray-500 |
| 技术ID | text-[10px] text-gray-400 font-mono |
行高与截断:正文 leading-relaxed,单行 truncate,多行 line-clamp-2
2.3 CSS 变量(src/index.css — 唯一真相)
:root {
/* 主题色 (Brand) */
--brand-primary: #3B82F6;
--brand-dark: #1E40AF;
--brand-light: #DBEAFE;
/* 强调色 (Accent) */
--accent-primary: #0EA5E9;
--accent-success: #10B981;
--accent-warning: #F59E0B;
--accent-error: #EF4444;
--accent-info: #3B82F6;
/* 底色 (Background) */
--bg-page: #F8FAFC;
--bg-container: #FFFFFF;
--bg-secondary: #F1F5F9;
--bg-tertiary: #F8FAFC;
--bg-hover: #F1F5F9;
--bg-selected: #E0F2FE;
--bg-disabled: #E2E8F0;
--bg-footer: #0E2E4F;
/* 文字色 (Text) */
--text-primary: #1E293B; /* ← 注意:不是 #0F172A */
--text-secondary: #475569;
--text-tertiary: #94A3B8;
--text-disabled: #CBD5E1;
--text-inverse: #FFFFFF;
/* 边框色 (Border) */
--border-default: #E2E8F0;
--border-hover: #CBD5E1;
--border-focus: #3B82F6;
--border-active: #0EA5E9;
/* 阴影 (Shadow) */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
--shadow-lg: 0 4px 6px rgba(0, 0, 0, 0.07), 0 2px 4px rgba(0, 0, 0, 0.06);
--shadow-xl: 0 10px 15px rgba(0, 0, 0, 0.1), 0 4px 6px rgba(0, 0, 0, 0.05);
/* 圆角 (Radius) — 精简三级 */
--radius-sm: 12px; /* 已废弃,映射到 --radius-md */
--radius-md: 12px; /* 12px — 理论默认(实际 rounded-lg = 16px,见顶部说明) */
--radius-lg: 16px; /* 16px — 弹窗/下拉/标准通用 */
--radius-xl: 16px; /* 已废弃,映射到 --radius-lg */
--radius-2xl: 16px; /* 已废弃,映射到 --radius-lg */
--radius-full: 9999px; /* 完全圆形 */
/* 过渡 (Transition) */
--transition-fast: 150ms ease;
--transition-normal: 200ms ease;
--transition-slow: 300ms ease;
/* 兼容旧变量(迁移期间保留,勿在新代码中直接使用) */
--color-primary: var(--brand-primary);
--color-secondary: var(--accent-primary);
--color-dark: var(--text-primary);
--color-darker: var(--brand-dark);
--color-gray: var(--text-secondary);
--color-gray-light: var(--border-default);
--color-gray-dark: var(--text-tertiary);
--gradient-dark: var(--bg-footer);
}
2.4 Tailwind Config(tailwind.config.js — 唯一真相)
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {
fontFamily: {
serif: ['Noto Serif SC', 'STSong', 'SimSun', 'serif'],
sans: ['-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'sans-serif'],
},
colors: {
brand: { primary: 'var(--brand-primary)', dark: 'var(--brand-dark)', light: 'var(--brand-light)' },
accent: { primary: 'var(--accent-primary)', success: 'var(--accent-success)',
warning: 'var(--accent-warning)', error: 'var(--accent-error)', info: 'var(--accent-info)' },
surface: { page: 'var(--bg-page)', container: 'var(--bg-container)', secondary: 'var(--bg-secondary)',
hover: 'var(--bg-hover)', selected: 'var(--bg-selected)', disabled: 'var(--bg-disabled)' },
content: { primary: 'var(--text-primary)', secondary: 'var(--text-secondary)',
tertiary: 'var(--text-tertiary)', disabled: 'var(--text-disabled)', inverse: 'var(--text-inverse)' },
line: { default: 'var(--border-default)', hover: 'var(--border-hover)',
focus: 'var(--border-focus)', active: 'var(--border-active)' },
black: '#000000',
white: '#FFFFFF',
},
spacing: {
'18': '4.5rem',
'22': '5.5rem',
},
borderRadius: {
sm: 'var(--radius-sm)', // 12px (deprecated)
md: 'var(--radius-md)', // 12px
lg: 'var(--radius-lg)', // 16px ← 标准通用圆角
xl: 'var(--radius-xl)', // 16px (deprecated)
'2xl':'var(--radius-2xl)', // 16px (deprecated)
full: 'var(--radius-full)', // 9999px
},
boxShadow: {
sm: 'var(--shadow-sm)', md: 'var(--shadow-md)',
lg: 'var(--shadow-lg)', xl: 'var(--shadow-xl)',
},
transitionDuration: {
fast: '150ms', normal: '200ms', slow: '300ms',
},
},
},
plugins: [],
}
三、配色场景
| 场景 | 使用时机 | 核心色调 |
|---|---|---|
| 产品内页(默认) | 话题列表/详情/配置/库 | 黑+白+灰,black/white/gray-* |
| 官网/主页 | Landing page / 营销页 | 蓝绿渐变 #5B9BD5 + #9FD4C4 |
不确定时,始终用产品内页风格。
产品内页速查
主色/CTA: #000000 (black)
页面背景: #FFFFFF (white)
卡片边框: gray-200
次边框: gray-100
悬停边框: gray-300 / black(激活)
主文字: text-black
描述文字: text-gray-600 / text-gray-700
次要文字: text-gray-500
技术标识: text-gray-400 font-mono
禁用: text-gray-400 opacity-50
选中背景: bg-gray-100
悬停背景: bg-gray-50
文字选中: ::selection { bg-black text-white }
官网/主页速查
--color-primary: #5B9BD5; /* 淡蓝 */
--color-secondary: #9FD4C4; /* 淡绿 */
--color-dark: #0E2E4F; /* 深海蓝(footer/heading) */
--gradient-primary: linear-gradient(135deg, #5B9BD5 0%, #9FD4C4 100%);
--gradient-secondary: linear-gradient(135deg, #6BC5D6 0%, #B5E5C8 100%);
--gradient-dark: linear-gradient(135deg, #0E2E4F 0%, #0A1F35 100%);
/* 渐变标题文字 */
.gradient-text {
background: var(--gradient-primary);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
语义状态色
| 状态 | 类 |
|---|---|
| Default | border-gray-200 text-gray-600 |
| Active/Selected | border-black text-black 或 bg-gray-100 |
| Disabled | text-gray-400 opacity-50 |
| Open | bg-green-50 text-green-700 |
| Running | bg-blue-50 text-blue-600 |
| Completed | bg-gray-100 text-gray-600 |
语义色统一封装在
.status-badge*CSS 类(见第九章),不允许各处临时映射。
四、圆角系统(代码实际值)
| Tailwind 类 | CSS 变量 | 实际值 | 使用场景 |
|---|---|---|---|
rounded-lg | var(--radius-lg) | 16px | 卡片/按钮/输入框/模态框(指南统一用此类) |
rounded-xl | var(--radius-xl) | 16px | 已废弃,等同 rounded-lg |
rounded-full | var(--radius-full) | 9999px | 头像/Chip/徽章 |
rounded-md | var(--radius-md) | 12px | 理论默认,当前实际用 rounded-lg |
禁止:自定义值 rounded-[XXpx]
五、组件代码模板(来自 frontend-design-guide.md)
5.1 按钮
// 主按钮
<button className="bg-black text-white px-4 py-1.5 rounded-lg text-sm font-serif font-medium hover:bg-gray-900 transition-colors disabled:opacity-50">
操作
</button>
// 次按钮
<button className="border border-gray-200 bg-white text-black px-4 py-1.5 rounded-lg text-sm font-serif font-medium hover:border-black transition-colors disabled:opacity-50">
次要操作
</button>
// 文字按钮
<button className="text-sm text-gray-500 hover:text-black transition-colors">返回</button>
// 图标按钮
<button className="p-2 rounded-lg text-gray-600 hover:text-black hover:bg-gray-100 transition-colors" aria-label="打开菜单">
<Icon />
</button>
// 圆形操作按钮(+/×)
<button className="w-7 h-7 rounded-full flex items-center justify-center bg-black text-white hover:bg-gray-800 transition-colors" aria-label="添加">+</button>
5.2 卡片
// 标准内容卡片(可点击,含响应式宽度)
<div className="flex flex-col gap-1 px-4 py-3 rounded-lg border border-gray-200 bg-white hover:border-gray-300 hover:bg-gray-50 transition-colors w-full min-w-0 sm:min-w-[200px] sm:max-w-[280px] sm:w-auto text-left cursor-pointer">
<span className="text-base font-serif font-semibold text-black truncate">标题</span>
<span className="text-sm font-serif text-gray-600 line-clamp-2">描述</span>
<span className="text-xs text-gray-500">元数据</span>
</div>
// 话题列表项
<div className="border border-gray-200 rounded-lg p-4 sm:p-6 hover:border-black transition-colors active:bg-gray-50 cursor-pointer">
{/* 内容 */}
</div>
// 选中态卡片(select 模式)
<div className={`rounded-lg border px-4 py-3 transition-colors cursor-pointer ${
isSelected
? 'border-gray-400 bg-gray-100'
: 'border-gray-200 bg-white hover:border-gray-300 hover:bg-gray-50'
}`}>
{/* 选中时按钮: bg-gray-400 text-white / 未选中: bg-black text-white */}
</div>
5.3 输入控件
<input
className="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm font-serif focus:border-black focus:outline-none transition-colors"
placeholder="输入内容"
/>
<textarea
className="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm font-serif focus:border-black focus:outline-none transition-colors resize-none"
rows={4}
/>
<label className="block text-sm font-serif font-medium text-black mb-2">字段名</label>
5.4 导航(TopNav)
<nav className="h-14 bg-white border-b border-gray-200 flex items-center px-4 sm:px-6 justify-between">
<span className="text-base font-serif font-bold text-black">他山</span>
<div className="hidden md:flex items-center gap-6">
<a className="text-sm font-serif text-black font-medium">激活页</a>
<a className="text-sm font-serif text-gray-500 hover:text-black transition-colors">其他</a>
</div>
<button className="bg-black text-white px-4 py-1.5 rounded-lg text-sm font-serif font-medium hover:bg-gray-900">登录</button>
<button className="md:hidden p-2 rounded-lg text-gray-600 hover:bg-gray-100" aria-label="打开菜单">☰</button>
</nav>
5.5 模态框
<div className="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4">
{/* 文档说 rounded-lg,与卡片一致 */}
<div className="bg-white rounded-lg shadow-xl border border-gray-200 max-w-2xl w-full max-h-[85vh] flex flex-col">
<div className="px-6 py-4 border-b border-gray-200 flex items-center justify-between">
<h2 className="text-lg font-serif font-semibold text-black">标题</h2>
<button className="text-gray-500 hover:text-black text-2xl" aria-label="关闭">×</button>
</div>
<div className="flex-1 overflow-auto px-6 py-4">{/* 内容 */}</div>
<div className="px-6 py-4 border-t border-gray-200 flex justify-end gap-3">
<button className="text-sm text-gray-500 hover:text-black">取消</button>
<button className="bg-black text-white px-4 py-1.5 rounded-lg text-sm font-serif font-medium hover:bg-gray-900">确认</button>
</div>
</div>
</div>
5.6 Tab 面板
<div className="flex gap-1 border-b border-gray-200 -mb-px overflow-x-auto scrollbar-hide">
{tabs.map(tab => (
<button key={tab.id}
className={`px-4 py-2 text-sm font-serif whitespace-nowrap border-b-2 transition-colors ${
activeTab === tab.id ? 'text-black font-medium border-black' : 'text-gray-500 hover:text-gray-700 border-transparent'
}`}
onClick={() => setActiveTab(tab.id)}>{tab.label}</button>
))}
</div>
{/* 内容带方向动画 */}
<div className={dir === 'right' ? 'animate-slide-in-right' : 'animate-slide-in-left'}>
{/* 内容 */}
</div>
5.7 Chip(标签/过滤器)
{/* 移动端 pill,桌面端 card */}
<div className="inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs bg-gray-100 border border-gray-200 sm:rounded-lg sm:px-3 sm:py-2 sm:min-w-[180px] sm:max-w-[280px] sm:bg-white sm:hover:border-gray-400 sm:hover:bg-gray-50 transition-colors">
<span className="font-serif text-black truncate max-w-[120px] sm:max-w-[220px]">标签文字</span>
<button className="w-5 h-5 sm:w-7 sm:h-7 rounded-full flex items-center justify-center text-gray-400 hover:text-black hover:bg-gray-200 transition-colors flex-shrink-0" aria-label="移除">×</button>
</div>
5.8 头像(Expert Avatar)
{/* w-6 h-6 或 w-7 h-7(指南两种尺寸) */}
<div className="w-6 h-6 rounded-full bg-black text-white flex items-center justify-center font-serif text-xs flex-shrink-0">
{name.charAt(0).toUpperCase()}
</div>
5.9 Spinner(加载)
{/* 使用 index.css 的 .spinner class */}
<span className="spinner" />
{/* 或直接 animate-spin */}
<div className="inline-block w-4 h-4 border-2 border-gray-200 border-t-black rounded-full animate-spin" />
六、布局与间距
容器宽度
<div className="max-w-6xl mx-auto px-4 sm:px-6"> {/* 内容库 */}
<div className="max-w-4xl mx-auto px-4 sm:px-6"> {/* 列表页 */}
<div className="max-w-2xl mx-auto px-4 sm:px-6"> {/* 表单/详情 */}
垂直节奏
页面内边距: py-6 sm:py-8
标题到内容: mb-6 sm:mb-8(或 mb-8 sm:mb-12)
卡片间距: gap-4
表单字段间: gap-6
主内容偏移: pt-14(TopNav 高度)
响应式模式
| 场景 | 移动端 | 桌面端 |
|---|---|---|
| 内边距 | px-4 py-6 | sm:px-6 sm:py-8 |
| 标题 | text-xl | sm:text-2xl |
| 导航 | 汉堡菜单 | md:flex 横向链接 |
| Chip | rounded-full 紧凑 | sm:rounded-lg 展开 |
| 网格 | 单列 | sm:grid-cols-2 lg:grid-cols-3 |
七、@layer base(index.css 实际定义)
@layer base {
html {
font-family: 'Noto Serif SC', STSong, SimSun, serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-tap-highlight-color: transparent;
scroll-behavior: smooth;
overscroll-behavior: none;
}
body {
font-feature-settings: "kern" 1, "liga" 1;
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
overflow-x: hidden;
background-color: var(--bg-page);
color: var(--text-primary);
min-height: 100vh;
overscroll-behavior: none;
}
::selection {
@apply bg-black text-white;
}
}
八、动画与工具类(index.css 实际定义)
动画关键帧(以代码为准,与设计文档有差异)
@layer utilities {
/* === 动画关键帧 === */
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0.2; }
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideInFromRight {
from { opacity: 0.6; transform: translateX(12%); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes slideInFromLeft {
from { opacity: 0.6; transform: translateX(-12%); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes nudgeRight {
0%, 100% { transform: translateX(0); opacity: 0.7; }
50% { transform: translateX(4px); opacity: 1; }
}
/* === 动画类 === */
.animate-spin { animation: spin 0.8s linear infinite; }
.animate-blink { animation: blink 1.2s ease-in-out infinite; }
.animate-fade-in { animation: fadeIn 0.15s ease-out; }
.animate-slide-in-right { animation: slideInFromRight 0.2s ease-out; }
.animate-slide-in-left { animation: slideInFromLeft 0.2s ease-out; }
.animate-nudge-right { animation: nudgeRight 2s ease-in-out infinite; }
/* === 工具类 === */
.prose-serif { font-family: 'Noto Serif SC', STSong, SimSun, serif; }
.border-thin { border-width: 0.5px; }
.safe-area-inset-top { padding-top: env(safe-area-inset-top); }
.touch-manipulation { touch-action: manipulation; }
.scroll-contain { overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.no-bounce { overscroll-behavior: none; touch-action: pan-y; }
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
.scrollbar-hide::-webkit-scrollbar { display: none; }
}
过渡规则:
- 常规状态变化 →
transition-colors(优先,避免 transition-all 引起布局抖动) - 可接受 →
transition-all duration-200 - Tab 切换 →
animate-slide-in-right/animate-slide-in-left - 触摸优化 →
touch-manipulation(消除 300ms 延迟)
九、预定义 CSS 组件类(index.css 实际定义,非 Tailwind 工具类)
/* === Spinner === */
.spinner {
@apply inline-block w-4 h-4 border-2 border-gray-200 border-t-black rounded-full animate-spin;
}
/* === Status Badge === */
.status-badge {
@apply inline-flex items-center px-2 py-0.5 text-xs border;
}
.status-badge-default { @apply status-badge border-gray-200 text-gray-600; }
.status-badge-active { @apply status-badge border-black text-black; }
/* === Expert Dot === */
.expert-dot-active { @apply w-2 h-2 rounded-full bg-black animate-blink; }
使用示例:
<span className="spinner" />
<span className="status-badge-active">进行中</span>
<span className="expert-dot-active" />
十、Markdown 内容渲染(以 index.css 实际代码为准)
包裹 react-markdown 输出用 .markdown-content 类(纯 CSS 选择器,非 @layer):
/* --- 基础 --- */
.markdown-content { @apply leading-relaxed text-black; font-family: 'Noto Serif SC', STSong, SimSun, serif; }
/* --- 标题(通用)--- */
.markdown-content h1, h2, h3, h4, h5, h6 { @apply mt-8 mb-4 font-bold text-black; font-family: 'Noto Serif SC', ...; }
.markdown-content h1 { @apply text-2xl border-b border-black pb-2; }
.markdown-content h2 { @apply text-xl border-b border-gray-200 pb-1; }
.markdown-content h3 { @apply text-lg; }
.markdown-content h4 { @apply text-base; }
/* --- 正文 --- */
.markdown-content p { @apply mb-4; }
.markdown-content p:last-child { @apply mb-0; }
.markdown-content ul, ol { @apply mb-4 pl-6; }
.markdown-content li { @apply mb-2; }
.markdown-content hr { @apply border-t border-gray-200 my-8; }
/* --- 链接 --- */
.markdown-content a { @apply text-black underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
.markdown-content a:hover { text-decoration-thickness: 2px; }
/* --- 图片(有完整样式!) --- */
.markdown-content img {
@apply block h-auto my-4 rounded-xl border border-gray-200 bg-gray-50 shadow-sm mx-auto;
max-height: min(72vh, 520px);
width: auto;
max-width: 100%;
object-fit: contain;
}
/* --- 代码 --- */
.markdown-content code { @apply bg-gray-100 px-1 py-0.5 text-sm; font-family: 'Courier New', Courier, monospace; }
.markdown-content pre { @apply bg-gray-900 text-white p-4 mb-4 overflow-x-auto; }
.markdown-content pre code { @apply bg-transparent p-0; }
/* --- 引用 --- */
.markdown-content blockquote { @apply border-l-2 border-black pl-4 my-4 text-gray-600 italic; }
/* --- 表格(注意:border-collapse,非 rounded) --- */
.markdown-content table { @apply w-full border-collapse mb-4 text-sm; }
.markdown-content th, .markdown-content td { @apply border border-gray-200 px-3 py-2 text-left; }
.markdown-content th { @apply bg-gray-50 font-semibold text-black; }
.markdown-content td { @apply text-gray-700; }
十一、无障碍(a11y)约定
// 图标按钮必须有 aria-label
<button aria-label="关闭菜单">×</button>
// 可展开元素
<button aria-expanded={isOpen} aria-label="切换菜单">
// 非 button 可点击
<div role="button" tabIndex={0} onKeyDown={e => e.key === 'Enter' && handleClick()} onClick={handleClick}>
// 下拉键盘支持
onKeyDown={(e) => {
if (e.key === 'ArrowDown') selectNext();
if (e.key === 'ArrowUp') selectPrev();
if (e.key === 'Escape') close();
}}
// 焦点(不允许无替代的 outline-none)
className="focus:border-black focus:outline-none" // ✅ 用边框替代
十二、禁止清单(与 frontend-brand-guard.mdc 同步)
❌ Inter / Roboto / Arial 作主字体
❌ 大面积渐变背景、紫色配色、通用 AI 风格
❌ 自定义圆角值 rounded-[XXpx]
❌ className 中硬编码颜色值(用 Tailwind 类或 CSS 变量)
❌ 可点击元素无 aria-label
❌ outline-none 无可见焦点替代
❌ Tab 切换和模态框以外的复杂动画
❌ 移动端点击区域 < 44×44px
❌ CSS-in-JS(styled-components / emotion)
❌ 新代码中直接使用旧兼容变量(--color-primary 等)
❌ 禁止:在浅色白色背景容器里使用深色背景专用配色(text-gray-200、text-blue-200、hover:bg-white/5、bg-black/20),这些在白色背景完全不可见
⚠️ 背景适配规则(2026-03-22 新增,避免重复踩坑)
浅色背景容器(--bg-container: #FFFFFF / bg-white / bg-gray-50)内的组件:
- ✅ 必须使用深色文字:
text-gray-700+、border-gray-200、bg-white、实色按钮 - ❌ 禁止:
text-gray-200、text-blue-200(浅色字在白底不可读) - ❌ 禁止:
hover:bg-white/5、bg-black/20(透明叠加在白底不可见)
深色背景容器(导航栏 / 地图画布 --nav-bg 等)内的组件:
- ✅ 可以使用:
text-gray-300/200、hover:bg-white/10
踩坑案例:DocTree 和 ProposalCard 使用了深色配色,放入白色 listPanel 后颜色失读。 建议为每个组件在注释中标注「适用背景:light / dark」,避免跨容器误用。
十三、权威文档路径
代码真相(优先):
/Users/boyuan/aiwork/0310_huaxiang\项目群\Tashan-TopicLab\frontend\
├── src\index.css ← CSS 变量/动画/@layer base/markdown 样式(唯一真相)
└── tailwind.config.js ← Tailwind 映射(唯一真相)
设计文档(语义说明,次级):
/Users/boyuan/aiwork/0310_huaxiang\项目群\Tashan-TopicLab\docs\design\
├── frontend-design-guide.md ← 完整设计语言(组件类名、布局、响应式)
├── color-system.md ← 配色变量语义说明
├── shape-system.md ← 圆角系统说明(⚠️ CSS 变量值与 index.css 不同)
├── tashan-homepage-style-guide.md ← 官网/主页风格
└── style-refactor-checklist.md ← 重构优先级清单
变更记录
2026-03-20 — v1.0 初始创建
见 history/SKILL_v1.0_20260320.md
2026-03-20 — v1.0 → v1.1 — 严格对齐 index.css 真相,修复全量偏差
根因:用户要求严格验证 SKILL 内容与 TopicLab 实际代码是否完全一致。逐行比对 index.css(真相)vs v1.0 发现多处严重偏差。
错误修复(有误的值):
--text-primary: #0F172A→ 修正为#1E293B(来自 index.css)fadeInkeyframe:移除了错误的translateY(4px)transform(index.css 无 transform)blinkkeyframe:修正为0%,100%{opacity:1} 50%{opacity:0.2} 1.2s ease-in-outslideInFromRight/Left:修正为translateX(12%/-12%)+opacity:0.6(非 16px + 0)- Modal 圆角:跟随 guide 用
rounded-lg(非rounded-xl) - Shape 表说明:修正
rounded-lg= 16px(非 12px),与 tailwind.config.js 实际映射一致
缺失内容补充:
- CSS 变量:补全
--bg-tertiary、--radius-sm/xl/2xl、旧兼容变量(--color-*) - Tailwind config:补全
accent.info、surface.disabled、content.disabled、spacing、transitionDuration、borderRadius '2xl' - 动画:补全
animate-spin、animate-nudge-right - 工具类:补全
.prose-serif、.border-thin、.scroll-contain、.no-bounce - 预定义 CSS 类:补全
.spinner、.status-badge*、.expert-dot-active - Markdown:补全
img样式、h4、p:last-child、hr、text-underline-offset、正确的table样式(border-collapse,非rounded) @layer base:补全完整 html/body 属性(overscroll-behavior、background-color、color、min-height等)- 卡片响应式:补全
min-w-0 sm:min-w-[200px] sm:max-w-[280px] sm:w-auto - Chip 桌面:补全
sm:min-w-[180px] sm:max-w-[280px]
验证结果:
- 正向验证:所有 CSS 变量值、keyframe 定义、组件类名均可从 index.css 找到对应源码
- 负向验证:无内容被删减,均为补充/修正(只增不减原则满足)
验证状态:✅ 已验证(逐行对照 index.css)
v1.2 — 2026-03-22 — 补充背景适配规则(project-retrospective-20260322)
根因:DocTree / ProposalCard 使用深色配色,放入白色 listPanel 后颜色失读——text-gray-200 在白底不可读,hover:bg-white/5 透明叠加在白底不可见。
修改内容:
- 新增:「⚠️ 背景适配规则」小节(位于禁止清单之后),区分浅色/深色容器配色要求,并附踩坑案例
验证结果:
- 正向验证:在浅色容器中使用深色组件时,AI 应提示违反背景适配规则 → 待验证
- 负向验证:在深色导航栏中使用
text-gray-300不触发警告 → 待验证
验证状态:🔵 待验证
备份路径:.cursor/skills/frontend-brand/history/SKILL_v1.1_20260322.md
What ships with it: 2 files
49.9 KB alongside SKILL.md
history/
- SKILL_v1.0_20260320.md22.7 KB
- SKILL_v1.1_20260322.md27.2 KB