# 间距与节奏硬规则

> 间距不是"感觉舒服就行"，而是**从一套数字里选**。不在数字表里的间距一律禁用。

---

## 一、8pt 栅格系统

所有间距值必须是 **4 或 8 的倍数**。选定一个后整个项目都用。

### 允许的间距值

```
4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 80, 96, 128, 160, 192, 256
```

### T-Shirt 命名（推荐写 token）

```css
:root {
  --space-xs:  4px;
  --space-sm:  8px;
  --space-md:  16px;   /* 基础单位 */
  --space-lg:  24px;
  --space-xl:  32px;
  --space-2xl: 48px;
  --space-3xl: 64px;
  --space-4xl: 96px;
  --space-5xl: 128px;
}
```

### 禁用

- ❌ `padding: 13px`、`margin: 7px`（非栅格值）
- ❌ 同一组件混用 `padding: 16px 17px`（破对称）
- ❌ 发明新间距值（先用已有的 token）

---

## 二、Fibonacci 留白节奏（大尺度版）

大型构图（幻灯片、海报、Hero 区域）推荐用 Fibonacci：

```
8, 13, 21, 34, 55, 89, 144, 233
```

好处：**相邻值差距大，视觉有戏剧节奏感**，不会像 8pt 栅格那样均匀到平淡。

适用场景：
- 幻灯片 title vs body 的间距
- 海报主视觉与文案区的分隔
- 杂志/书籍类排版

---

## 三、垂直节奏（Baseline Grid）

### 基础规则

**每个段落 / 组件的高度** 应该是 **基础行高的整数倍**。

```css
:root {
  --baseline: 24px;   /* base line-height */
}

p  { line-height: 24px; margin-bottom: 24px; }     /* 1 × baseline */
h3 { line-height: 32px; margin-bottom: 48px; }     /* 2 × baseline */
h2 { line-height: 48px; margin-bottom: 72px; }     /* 3 × baseline */
```

### 结果

全页面所有文字**底线（baseline）对齐到同一张隐形网格**。专业印刷品都这样。

---

## 四、Hit Target（可点击区域）

| 平台 | 最小 | 推荐 |
|------|------|------|
| 移动端 | **44 × 44 px** | 48 × 48 px |
| 桌面端 | **32 × 32 px** | 40 × 40 px |
| 密集工具栏 | 24 × 24 px | 28 × 28 px |

**规则**：可视图标可以 ≤ 24px，但**hit target（带 padding 的可点击区域）必须达到最小值**。

---

## 五、对齐（Alignment）

### 左对齐 vs 居中 vs 两端对齐

| 场景 | 推荐 |
|------|------|
| 正文段落 | **左对齐**（中英都是） |
| 标题（≤ 2 行） | 居中 OK |
| 标题（> 2 行） | **左对齐** |
| 数字列 / 价格 | 右对齐 |
| 表格 | 按列类型：文字左对齐，数字右对齐 |
| 中英混排正文 | **左对齐**，不要两端对齐（中英字宽差异会产生丑空格） |

### 禁用

- ❌ 多行标题居中（读起来眼睛要跳）
- ❌ 短正文两端对齐（产生白河/white rivers）

---

## 六、留白三原则

### 1. 最重要的东西周围留白最多

```
Hero 区 上下留白 128px
Section 之间 64-96px
卡片内部 padding 24-32px
文字行距 8-12px
```

越重要 → 越多空间呼吸。

### 2. 相关元素靠近，不相关元素远离（Gestalt 邻近原则）

```css
/* ✅ 正确 */
.card {
  title       → 距离 description 8px
  description → 距离 metadata 16px
  metadata    → 距离下一个卡片 48px
}

/* ❌ 错误：所有间距都一样 */
.card {
  所有间距 16px  /* 看不出哪些是一组 */
}
```

### 3. 外部留白 > 内部留白

卡片与卡片之间的间距 **大于** 卡片内部的 padding。否则看起来像一大坨。

```css
.card { padding: 24px; }
.card-grid { gap: 48px; }   /* gap 2x padding */
```

---

## 七、边框半径（border-radius）

统一一套，不要每个组件发明新半径。

```css
:root {
  --radius-sm:   4px;   /* 小 tag */
  --radius-md:   8px;   /* 按钮、输入框 */
  --radius-lg:   12px;  /* 卡片 */
  --radius-xl:   20px;  /* 大 panel */
  --radius-full: 9999px; /* 圆 / pill */
}
```

### 规则

- **同一层级用同一半径**（所有卡片都是 12px）
- 嵌套时：**内部 < 外部**（外 card 12px → 内 badge 6px）
- 极简风格：**全部 0 或全部 8px**，不混用
- 禁用 `border-radius: 16px 4px 16px 4px` 这种非对称圆角（2010 年风）

---

## 八、阴影（shadow）系统

最多 3 档，不要每个元素都发明新阴影：

```css
:root {
  /* 柔和、偏真实的阴影（非 Material Design 的重阴影）*/
  --shadow-sm: 0 1px 2px rgba(0,0,0,.04), 0 1px 3px rgba(0,0,0,.06);
  --shadow-md: 0 4px 12px rgba(0,0,0,.06), 0 2px 4px rgba(0,0,0,.04);
  --shadow-lg: 0 12px 40px rgba(0,0,0,.08), 0 4px 12px rgba(0,0,0,.06);
}
```

### 规则

- 阴影 **永远是多层叠加**（1 层硬阴影会显得廉价）
- `rgba` 的 alpha 值 ≤ 0.12，不然太重
- 深色模式下阴影要显著减弱或改用边框代替

---

## 九、自检清单

- [ ] 所有 padding/margin 都是 4 或 8 倍数
- [ ] 定义了 3-5 档 space token，没有 inline 魔术数
- [ ] hit target ≥ 44px（手机）或 32px（桌面）
- [ ] 相关元素间距 < 不相关元素间距（至少 2x 关系）
- [ ] 外间距 > 内间距
- [ ] border-radius 统一 token，不混用
- [ ] 阴影最多 3 档
