# Prompt — CANONICAL-006 Pagination figma alignment refactor (1 prompt 一刀 fix 7 mismatch + hierarchy)

> **角色**：executor
> **范围**：refactor `src/components/Pagination/Pagination.vue` template hierarchy + CSS 一次性修 7 mismatch，让 canonical 对齐 figma 真源（grounded by Figma MCP `get_design_context` 实证）
>
> ⚠️ **不要 commit / 不要 git add**——与 A4.2-safe Pagination sample 同 commit
> ⚠️ 完成后 **STOP**，按 §4 完成报告格式回报；§4 必须含 §4.X 完整改动清单段
> ⚠️ **不扩范围**：只动 `src/components/Pagination/Pagination.vue` 一个文件 + 重跑 audit / typecheck
> ⚠️ **typecheck 失败 → STOP 报告**，不要自由发挥加 conditional renders / type cast 替代正确实现

---

## §0 — Plan owner 已定裁定（grounded in Figma MCP truth）

### Figma 真源 (实证 source: `get_design_context(fileKey=YbsPRUVmNdsbN40NNwh1Gn, nodeId=4894:7210)`)

**Pagination outer hierarchy** (all variants):

```
.pagination (flex gap 24px)  ← --spacing/l
  ├─ .pg-total (1-20 of 1,299)
  ├─ .pg-pagesize (Select 20/Page, w 120px h 32px)
  └─ .pg-content (flex gap 24px)  ← --spacing/l
      ├─ .pg-nav-row (variant-specific gap, see below)
      └─ .pg-jumper (flex gap 8px) ← --spacing/xs
          ├─ Go to label
          └─ Input (w 64px h 32px)
```

**Variant-specific differences**:

| Variant | nav-row layout | nav-row gap | Selector style | Input style |
|---|---|---|---|---|
| Classic | `< 1 2 3 4 5 >` | **8px** (`gap-[8px]`) | filled (bg #353535, no border) | filled (bg #353535) |
| Small | `< 1 2 3 4 5 >` | **4px** (`--spacing/xxs`) | line (border) | line (border) |
| Simple | `< >` only | n/a — `w-[80px] justify-between` | filled (same as Classic) | filled (same as Classic) |

**Page button styling** (32×32 square, radius 4px):

| Variant | Inactive bg | Inactive border | Active bg | Active text | Active font-weight |
|---|---|---|---|---|---|
| Classic | `var(--line-deep)` (#353535) | **none** | `var(--brand)` (#2fb54e) | white | **400** |
| Small | transparent | none | transparent | `var(--brand)` | 400 |

(figma token alias: `--color-type/background/layer_4` (#353535) 对应 canonical 已有 `var(--line-deep)`，不新增 token)

### 7 mismatch list (canonical 现状 vs figma 真源)

| # | 项 | Figma 真源 | Canonical 现状 | Fix |
|---|---|---|---|---|
| 1 | Classic nav row gap | 8px | `.pg-main` 24px | nav-row sub-frame gap 8px |
| 2 | Small nav row gap | 4px | `.pg-main` 24px | nav-row sub-frame gap 4px |
| 3 | Simple `<>` layout | w 80px + `justify-between` | `.pg-main` 16px gap | `.pg-nav-row.simple` w 80px justify-between, no gap |
| 4 | Classic page button inactive bg | `var(--line-deep)` (#353535) | `transparent` | `.pg-btn { background: var(--line-deep) }` |
| 5 | Classic page button border | none | `1px solid var(--line-border)` | `.pg-btn { border: none }` |
| 6 | Classic active font-weight | 400 | 600 | `.pg-btn--active { font-weight: 400 }` |
| 7 | Small page button min-width | 32px (figma `size-[32px]`) | `24px` (`.pg-btn--flat`) | `.pg-btn--flat { min-width: 32px }` |

### Hierarchy refactor 是必要的（实施 1-3 自然要求）

当前 `.pg-main` 把 selector + arrows + numbers + jumper 全打包，flat 24px gap——与 figma "outer 4 sections + content sub-frame" 不符。

**Refactor 方案**：
- 删 `.pg-main` wrapper
- 顶层 `.pagination` 直接子节点：`.pg-total` | `.pg-pagesize` | `.pg-content` | (no .pg-extra; jumper 移入 content)
- 新增 `.pg-content` wrapper (gap 24px) 内部包 `.pg-nav-row` + `.pg-jumper`
- nav-row class 变种：默认 (Classic/Small 共用) gap 8/4px；`.pg-nav-row--simple` w 80px justify-between
- `.pg-extra` `.pg-jumper` 合并为 `.pg-jumper`

### 改 .pg-btn / .pg-btn--flat / .pg-btn--active CSS

```css
.pg-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  font-size: 14px;
  font-family: inherit;
  border-radius: 4px;
  border: none;          /* fix #5 */
  background: var(--line-deep);  /* fix #4: figma --color-type/background/layer_4 */
  color: var(--text-2);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  outline: none;
}

.pg-btn:hover:not(:disabled) {
  background: var(--bg-layer3);
  color: var(--text-body);
}

.pg-btn--active {
  background: var(--brand);
  color: var(--text-primary-btn);
  font-weight: 400;       /* fix #6: figma 真源 font-normal */
}

.pg-btn--flat {
  width: 32px;            /* fix #7 */
  background: transparent;
}

.pg-btn--flat.pg-btn--active {
  background: transparent;
  color: var(--brand);
}
```

(原 `.pg-btn--text-active` 类删除，逻辑合并到 `.pg-btn--flat.pg-btn--active`)

### 改 .pg-arrow (prev/next button) 同 page button styling

`.pg-arrow` Classic 应同 page button (bg `--line-deep`, no border)，Small `.pg-arrow.pg-btn--flat` transparent。

### 改 .pagination CSS 顶层

```css
.pagination {
  display: flex;
  align-items: center;
  gap: 24px;             /* ✅ 已对齐 figma --spacing/l */
  flex-wrap: wrap;
}

.pg-content {           /* 新 */
  display: inline-flex;
  align-items: center;
  gap: 24px;            /* figma --spacing/l */
  flex-wrap: wrap;
}

.pg-nav-row {           /* 新 — Classic 默认 */
  display: inline-flex;
  align-items: center;
  gap: 8px;             /* fix #1 — figma 真源 */
}

.pg-nav-row--small {    /* Small 变种 */
  gap: 4px;             /* fix #2 — figma --spacing/xxs */
}

.pg-nav-row--simple {   /* Simple 变种 */
  gap: 0;
  width: 80px;
  justify-content: space-between;  /* fix #3 — figma 真源 */
}

.pg-jumper {            /* 改名（原 .pg-extra .pg-jumper 合并） */
  display: inline-flex;
  align-items: center;
  gap: 8px;             /* figma --spacing/xs */
}
```

删 `.pg-main` / `.pg-extra` / `.pagination--simple .pg-main` 等不再用的 selectors。

### Template 重构

```vue
<template>
  <div class="pagination" :class="[`pagination--${type.toLowerCase()}`]">
    <span v-if="resolvedShowTotal" class="pg-total">
      {{ visibleRangeStart }}-{{ visibleRangeEnd }} of {{ total.toLocaleString() }}
    </span>

    <div v-if="resolvedShowPageSizeSelector" class="pg-pagesize">
      <Select
        :model-value="pageSize"
        :variant="pageControlVariant"
        size="m"
        :options="normalizedPageSizeOptions"
        @update:model-value="onPageSizeChange"
      />
    </div>

    <div class="pg-content">
      <div
        class="pg-nav-row"
        :class="{
          'pg-nav-row--small': isSmall,
          'pg-nav-row--simple': isSimple,
        }"
      >
        <button
          class="pg-btn pg-arrow"
          :class="{ 'pg-btn--flat': isSmall }"
          :disabled="currentPage <= 1"
          aria-label="Previous"
          @click="go(currentPage - 1)"
        >
          <Icon name="previous" class="pg-arrow__icon" />
        </button>

        <template v-if="resolvedShowPageNumbers">
          <template v-for="p in pages" :key="p">
            <span v-if="p === '...'" class="pg-ellipsis">…</span>
            <button
              v-else
              class="pg-btn"
              :class="{
                'pg-btn--active': currentPage === p,
                'pg-btn--flat': isSmall,
              }"
              @click="go(p)"
            >{{ p }}</button>
          </template>
        </template>

        <button
          class="pg-btn pg-arrow"
          :class="{ 'pg-btn--flat': isSmall }"
          :disabled="currentPage >= pageCount"
          aria-label="Next"
          @click="go(currentPage + 1)"
        >
          <Icon name="next" class="pg-arrow__icon" />
        </button>
      </div>

      <div v-if="resolvedShowJumper" class="pg-jumper">
        <span class="pg-jumper__label">Go to</span>
        <Input
          v-model="jumperValue"
          size="s"
          :variant="pageControlVariant"
          placeholder="Page"
          @keydown.enter="submitJumper"
          @blur="submitJumper"
        />
      </div>
    </div>
  </div>
</template>
```

### 不动

- 任何其他 file（generator / canonical wrapper / other page / 真源 .md / AGENTS / backlog / 复盘）
- `src/canonical/Pagination.vue` (wrapper 不动)
- `src/components/Icon|Input|Select` (canonical sub-components 不动)
- prop API (`type` / `modelValue` / `total` / `pageSize` / `showTotal` / `showJumper` / `showPageSizeSelector`) — 全保持

### 预期 typecheck

`pnpm exec vue-tsc --noEmit` **0 错误**。如果 fail → STOP 报告（不要自由发挥加 type cast / conditional 折中）。

### 预期 audit verdict

- 18 page audit reports：**全部仅 timestamps 改动**（template/CSS refactor 不影响 SFC scan-based audit verdict）
- PaginationPage 5+1 verdict 保持

### 预期 dev 视觉

- Classic: `<` 1 2 3 4 5 `>` 之间 gap 8px（更紧密）；page button 有深灰 bg #353535，无 border；active page 1 brand 绿 bg + 白文字 (font-normal 不再粗体)
- Small: `<` 1 2 3 4 5 `>` 之间 gap 4px (更紧密)；page button transparent + 32×32 (不再 24px squish)；active page 1 transparent bg + brand 绿文字
- Simple: `<` `>` 在 80px wide row 内 justify-between（中间空 ~16px）
- 三种 variants 与 outer total / selector / jumper 之间 gap 24px (与之前一致)

---

## §1 — 必读输入

按顺序：

1. [`AGENTS.md`](../../../AGENTS.md) — 硬规则
2. [`docs/meta-rules.md`](../../meta-rules.md) — 反模式 + 触发器
3. [`src/components/Pagination/Pagination.vue`](../../../src/components/Pagination/Pagination.vue) — 待 refactor (~327 行)
4. [`src/canonical/Pagination.vue`](../../../src/canonical/Pagination.vue) — wrapper (不动，理解 prop forward)
5. [`src/tokens/variables.css`](../../../src/tokens/variables.css) — 验证 `--line-deep` (#353535) / `--brand` / `--text-2` / `--text-primary-btn` 都已定义
6. [`playground/docs/pages/PaginationPage.vue`](../../../playground/docs/pages/PaginationPage.vue) — A4.2-safe sample，dev verify 用

---

## §2 — 任务清单

### 任务 2.1 — refactor template + CSS

按 §0 重构 hierarchy + 改 7 mismatch CSS。

### 任务 2.2 — typecheck

```bash
pnpm exec vue-tsc --noEmit
```

期望：0 错误。fail → STOP 报告。

### 任务 2.3 — 跑 audit 全量

```bash
node figma-sync/audit-page-t2-sample.mjs
```

### 任务 2.4 — Verify 18 reports timestamp-only

```bash
git diff --stat docs/internal/t2-sample-audit-report.*.md
```

### 任务 2.5 — dev 启动等 plan owner 截图

```bash
pnpm dev
```

启动后 STOP 等 plan owner 截图确认。

---

## §3 — 验收清单

- [ ] template hierarchy refactor (`.pg-main` 删 → `.pg-content` 加 → 内部 `.pg-nav-row` + `.pg-jumper`)
- [ ] CSS 7 mismatch 全 fix (gap 8/4 / Simple 80px justify-between / inactive bg / no border / font-weight 400 / Small min-width 32px)
- [ ] prop API 不变 (type/modelValue/total/pageSize/showTotal/showJumper/showPageSizeSelector)
- [ ] vue-tsc 0 错
- [ ] 18 baseline 仅 timestamps
- [ ] PaginationPage 5+1 verdict 保持
- [ ] dev 启动等 plan owner 截图（不自评）
- [ ] 不动其他文件
- [ ] 没 commit / 没 git add

---

## §4 — 完成报告

```
## CANONICAL-006 Pagination figma alignment refactor 完成报告

### 改动文件 (按 prompt 任务的预期 scope)
- src/components/Pagination/Pagination.vue (template + CSS refactor)
- docs/internal/t2-sample-audit-report.<18>.md (重生, 仅 timestamps)

### §4.X 完整改动清单 (All M / A / D, 含 prompt 范围外)
[git status --short 全列表]
[如有范围外改动，标 ⚠️ 解释]

### Refactor diff stat
[git diff --stat src/components/Pagination/Pagination.vue]

### 7 mismatch fix self-check
- [ ] Classic nav row gap 8px
- [ ] Small nav row gap 4px
- [ ] Simple <> 80px w/ justify-between
- [ ] Classic page button inactive bg --line-deep
- [ ] Classic page button no border
- [ ] Classic active font-weight 400
- [ ] Small page button min-width 32px

### typecheck
- vue-tsc: 0 错误 / X 错误（如 fail STOP）

### audit verdict
- 18 reports: 仅 timestamps OK / 偏离

### dev 视觉
- pnpm dev 启动: OK
- 等 plan owner 截图（executor 不自评）

### 验收 self-check
- [ ] template hierarchy refactor done
- [ ] 7 CSS mismatch fix done
- [ ] prop API 不变
- [ ] vue-tsc 0 错
- [ ] 18 baseline timestamp-only
- [ ] dev 启动等 plan owner
- [ ] 不动其他文件
- [ ] 没 commit
- [ ] §4.X 完整改动清单已列

### 未解决项 / blocker
[如有 token 缺失（如 --bg-layer4）/ class chain 冲突 / typecheck 失败，STOP 报告]
[无 blocker 写"无"]

STOP — 等 plan owner 复审 + 截图确认 → A4.2-safe Pagination sample (含本 refactor + cellMinWidth + 复盘 #14) 一并 commit → 进 A4.2-safe batch 3 page。
```

---

## §5 — 严守约束总览

- ⚠️ **不要 commit / 不要 git add**
- ⚠️ §0 文件改动**精确 1 文件** (Pagination.vue) + audit 重跑 + typecheck
- ⚠️ §4 完成报告**必须含 §4.X 完整改动清单段**
- ⚠️ dev 视觉**不自评**——启动 dev 后 STOP 等 plan owner 截图
- ⚠️ **prop API 不变** (canonical wrapper / consumer 不破坏)
- ⚠️ **typecheck 失败 / token 缺失 → STOP 报告**，不要自由发挥
- ⚠️ 完成 STOP，按 §4 格式回报
