## 样式（CSS/SCSS）与 UnoCSS 使用规范（Cursor Rules）

目标：在不牺牲可读性的前提下最大化复用，减少冗余，保证小程序/H5 多端一致、整洁大方。

### 1) 总原则
- 优先使用 UnoCSS 工具类与已定义的 shortcuts，避免重复造轮子。
- 同一工具类组合在同一页面或多个页面中出现 ≥ 2 次时，提取为“语义化类名”。
- 禁止使用 `@apply`，禁止在 SCSS 中重复定义 UnoCSS 已提供的工具类或在 `unocss.config.ts` 中已存在的 shortcuts（如：`flex`、`flex-start`、`flex-between`、`flex-col-center` 等）。
- 组件库样式覆盖和页面布局样式分离：页面/组件的布局与样式用普通类，覆盖 wot 组件样式用“外部样式类”。

### 2) 目录与作用域
- 页面私有样式：写在当前 `.vue` 的 `<style lang="scss" scoped>` 中。
- 多处复用的语义化样式：优先抽到所属页面/模块级样式；跨页面复用再考虑提到 `src/styles` 公共样式文件。
- 避免把零碎的、只出现一次的样式放到全局，保持全局样式轻量。

### 3) 覆盖 wot-design-uni 组件样式（外部样式类）
- 使用 `custom-class` 传入类名，禁止对 wot 组件使用 `class` 覆盖样式。
- 因为 SFC `scoped`，覆盖子组件需使用 `:deep()`，并加 `!important` 提升优先级。
- 在“自定义组件”中使用 wot 组件时，若样式穿透无效，按需开启 `styleIsolation: 'shared'`。
- 参考文档：[小程序使用外部样式类（wot-design-uni）](https://wot-design-uni.pages.dev/guide/common-problems.html#%E5%B0%8F%E7%A8%8B%E5%BA%8F%E4%BD%BF%E7%94%A8%E5%A4%96%E9%83%A8%E6%A0%B7%E5%BC%8F%E7%B1%BB)

示例（按钮）：

```vue
<wd-button custom-class="logout-button" plain @click="handleLogout">退出登录</wd-button>
```

```scss
/* 页面/组件内 */
:deep(.logout-button) {
  width: 100% !important;
  height: 80rpx !important;
  font-size: 32rpx !important;
  font-weight: bold !important;
  border-radius: 40rpx !important;
}
```

### 4) UnoCSS 约定与最小用法
- 预设、shortcuts 位于 `unocss.config.ts`，不要在 SCSS 中重复定义这些类。
- 常用 shortcuts（已存在，无需再自定义）：
  - `flex-start`、`flex-between`、`flex-center`、`flex-col-center` 等。
- 可以自由组合 UnoCSS 工具类（如：`p-20rpx`、`px-24rpx`、`border-b` 等）。
- 不可读的长串组合若重复使用，抽成语义化类名。
- 复杂/冗长的原子类组合（例如包含 ≥4 个原子类，且会在项目内重复出现）一律改为“外部样式类”（语义化类名），以避免模板膨胀；模板仅保留必要的少量工具类。
 - 简单、一次性且语义明确的区域优先使用 UnoCSS 原子类（例如单个 `p-30rpx`、`text-center`、`font-600` 等）；
   复杂/冗长（≥4）或会复用的组合抽为“外部样式类”。

示例（页面语义化类）：

```vue
<view class="card-header">...</view>
```

```scss
.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20rpx 24rpx;
  border-bottom: 1rpx solid #e5e7eb;
}

:deep(.dark) .card-header { border-bottom-color: #374151; }
```

### 5) 语义化抽取的判定标准
- 满足以下任一条件即可抽取为语义化类名：
  - 同一工具类组合在项目内出现 ≥ 2 次；
  - 该区域具备明确的语义（如“卡片头部”、“工具项”等）；
  - 需要在暗色模式等主题下统一控制样式。

推荐命名：`kebab-case`，表达语义而非表现形式，例如：`card-header`、`tool-item`、`user-profile`。

### 6) 属性书写顺序（遵循项目 Linter）
- 基本顺序：`display` → 布局（如 `flex-*`：先 `align-items`，后 `justify-content`）→ 尺寸（`width/height`）→ 间距（`margin/padding`）→ 背景 → 边框 → 圆角 → 阴影 → 过渡/变换。
- 避免无意义的属性覆盖；必要时使用 `!important`，仅用于外部样式类覆盖。

### 7) 深色模式
- 使用 `:deep(.dark) .your-class { ... }` 定义暗色样式，保持与明亮模式同一语义类名。

### 8) 示例对照（本项目中已落地）
- 将重复的工具项组合 `w-1/4 flex-col-center mb-30rpx` 抽取为：
  - `tool-item`（语义化类，含列方向与对齐、宽度 25%、下间距）
- 将重复的卡片头部组合 `flex-between p-20rpx px-24rpx border-b ...` 抽取为：
  - `card-header`（统一控制边距、分隔线与暗色模式）
- 将数据统计卡片 `flex p-30rpx mx-30rpx my-20rpx bg-white rounded-16rpx shadow-sm dark:bg-gray-800` 抽取为：
  - `stats-card`、`stats-item`、`stats-divider`（统一控制布局/间距/暗色色板）
- 覆盖 wot 组件样式：
  - 使用 `custom-class` + `:deep()` + `!important`，不要用 `class`。

### 9) 禁止项（务必遵守）
- 不要在 SCSS 中定义 `.flex`、`.flex-start`、`.flex-between` 等已由 UnoCSS/shortcuts 提供的类。
- 不要再使用 `@apply`。
- 不要把一次性的样式放到全局公共样式。

---
本规则文件旨在为 Cursor 自动补全与协作提供统一参考，遇到冲突以项目 Lint 规则与 `unocss.config.ts` 为准。

