# Pool Hadiah · 设计规范

视觉风格:暗金 + 品红的节日感 + 宝藏宝箱的游戏化隐喻。
设计基准:375 × 812(iPhone 标准),所有尺寸等比缩放到 vw。

---

## 色彩 Token

```
/* Background */
--bg-0      #1a0320   深紫底色
--bg-1      #2d0b3a   中紫
--bg-2      #4a1232   暗红紫

/* Gold (主色/点缀) */
--gold-1    #ffe9a8   高亮金
--gold-2    #ffc24b   主金
--gold-3    #e28b14   深金
--gold-4    #8a4a0a   金属投影

/* Accent (强调) */
--red       #ff3f6e   粉红(任务槽位/主 CTA 辅助)
--pink      #ff6fa8   浅粉
--green     #4adc70   成功/+10 浮字

/* Neutral */
--ink       #1a0320   按钮文字
--paper     #fff7e2   卡片高亮
```

背景不是纯色:三层叠加,顶部玫红径向渐变 + 底部紫蓝径向渐变 + 整体紫黑线性渐变,
上面再盖一层 8% 不透明度的噪声图以避免色带,最后 conic 光芒慢速旋转。

---

## 字体

| 用途 | 字体 | 字重 | 字号 |
|---|---|---|---|
| 标题(Pool Hadiah) | Fraunces | 900 | 38px |
| Eyebrow (EVENT SPESIAL) | DM Sans | 500 | 10px tracking 4px |
| 副标题 | DM Sans | 400 | 12px |
| 奖池数字 | Bebas Neue | 400 | 44px |
| 中奖数字 | Bebas Neue | 400 | 88px |
| 按钮文字 | Fraunces | 900 | 18px tracking 4px |
| 正文 | DM Sans | 400 | 11-13px |

字号最终会被 postcss 转成 vw,在 iPhone SE 会略小,在 Plus 系列会略大。

---

## 间距规范

```
外边距横向  20px
卡片内边距  14-18px
卡片间距    10-14px
按钮高度    56px (主) / 42px (次)
圆角        14-16px (卡片) / 56px (主按钮) / 42px (次按钮)
```

---

## 组件布局(375 × 812 基准)

```
 0  ┌──────────────────────────────┐
 14 │  ‹      [Aturan ›]            │  TopBar 46px
 46 │                                │
 50 │     [EVENT SPESIAL]            │
 66 │       Pool Hadiah              │  Title 70px
100 │  Undang Teman · Bagi Hadiah   │
120 │                                │
134 │  ┌ Pool Card ─────────────┐    │
    │  │ Total Pool    • LIVE    │   │  PoolCard 108px
    │  │ [🪙] 8,420  KOIN        │   │
    │  │ 2,817 peserta  ·  +10   │   │
244 │  └─────────────────────────┘   │
254 │  ┌ Task Card ─────┬──────┐     │
    │  │ Undang 3 Lv.2  │+10   │     │  TaskCard 82px
    │  │ ⚫⚫○ 1/3       │ KOIN │     │
    │  │ +10 koin/teman │Undang│     │
336 │  └────────────────┴──────┘     │
340 │                                │
    │        ┌ Scene ┐               │
    │       │  ☀️🧰  │               │  Scene 240px
    │       │        │               │
580 │       └────────┘               │
590 │  Putaran  03 : 42 : 18         │
610 │  [ BUKA SEKARANG ]              │  Bottom 202px
670 │  👥 Jihan baru dapat 12 Koin   │
690 │  Hak penuh · ShortPro          │
812 └──────────────────────────────┘
```

中奖揭晓后,`.scene` 里出现 Prize Reveal(绝对定位居中),
底部按钮切换为 `Tarik Lagi` + `Undang Teman · Pool Naik` 两列。

---

## 动画时间轴

### 常态(idle)
```
bg-rays       旋转一圈 40s, 循环
halo          脉冲 3s 一个呼吸
chest         上下浮动 3s 一周期 (-6px)
sparkle       16 颗,上升 6-14s,opacity 0 → 1 → 0
CTA rings     两圈交替外扩 2.2s,delay 1.1s
live msg      每 2.8s 换一条
pool +10      每 3.2-4.7s 一次,count-up 500ms
```

### 开奖中(revealing)
```
0 ms    click → stage 切到 .revealing
        按钮变 spinner
        震动 [30,40,30,40,80]
        chest 开始 0.15s 剧烈抖动
        halo 改 0.4s 快速脉冲
        scene-rays opacity 0 → 0.8, 周期从 8s 变 1.5s
1800 ms 切到 .revealed(后端结果必须这时候到齐)
```

### 揭晓(revealed)
```
0 ms      chest 播 openBounce 0.8s(scale 1 → 1.15 → 1.05)
          lid 用 0.6s cubic-bezier(.3,1.6,.5,1) 翻转 -35deg
          震动 [50,30,100]
          28 枚金币径向飞散 1.6s(随机 0-0.3s 延迟)
          50 片彩纸下落 1.8-3.2s(随机)
          prize-reveal 播 prizePop 0.8s(scale 0.3 → 1.1 → 1)
          prize 数字 count-up 1000ms(easeOutCubic)
          pool 数字扣除 count-up 900ms
300 ms    actions 行滑入(opacity + translateY)
```

### 任务进度变化
```
slot fill   0.5s cubic-bezier(.3,1.5,.5,1) 弹跳出现
pool bump   +10 绿色浮字 1.4s 向上飘
mission 完成 Toast 2.5s,震动 [40,20,80]
task-card   切到 .done,背景转绿
```

---

## 特效配置

| 元素 | 数量 | 分布 | 时长 |
|---|---|---|---|
| Sparkle | 16 | 全屏随机 x | 6-14s 循环 |
| Coin burst | 28 | 径向均分 + 抖动 | 1.6s |
| Confetti | 50 | 顶部随机 x | 1.8-3.2s |

低端机(hardwareConcurrency ≤ 4)下:
- Sparkle 隐藏
- bg-rays 隐藏
- grain 隐藏
- backdrop-filter 关闭
- 粒子总数维持(视觉主 payoff 不能砍)

---

## 文案总表(印尼语)

| 位置 | 文案 |
|---|---|
| Eyebrow | EVENT SPESIAL |
| Title | Pool Hadiah |
| Subtitle | Undang Teman · Bagi Hadiah Bersama |
| Rules button | Aturan › |
| Pool label | Total Pool Hari Ini |
| Pool live dot | LIVE |
| Pool unit | KOIN |
| Pool meta left | {N} peserta |
| Pool meta right | Setiap user baru = +10 Koin |
| Task title | Undang 3 Teman ke Lv.2 |
| Task sub | Tiap teman Lv.2: Pool +10 Koin |
| Task progress | {N} / 3 |
| Task done | ✓ Misi selesai, hadiah sudah masuk |
| Reward badge | +10 KOIN |
| Invite button | Undang / Tersalin ✓ |
| Countdown | Putaran berikutnya {hh}:{mm}:{ss} |
| Main CTA | BUKA SEKARANG |
| Loading | Sedang membuka... |
| Prize label | SELAMAT! KAMU DAPAT |
| Prize unit | KOIN |
| Prize tag | Sudah masuk dompet ✦ |
| Action 1 | Tarik Lagi |
| Action 2 | Undang Teman · Pool Naik |
| Live feed | {Name} baru saja dapat {N} Koin |
| Toast invite | 🔗 Link undangan tersalin |
| Toast mission | 🎉 Misi Selesai! +10 Koin masuk dompet |
| Legal | Hak penuh event ini milik ShortPro |

---

## 按钮状态

主按钮 `.draw-btn` 有四种视觉状态:

| 状态 | 背景 | 文字颜色 | 投影 | 可点击 |
|---|---|---|---|---|
| 默认 (`idle`) | 金色 `#ffe9a8 → #ff7a2e` | 深棕 `#4a1a03` | 金色深投影 + 橙色光晕 | 是 |
| 加载中 (`is-loading`) | 暗金 `#c9a066 → #a87a3a` | 暗棕 60% | 同默认 | 否 |
| 灰态 (`is-disabled`) | 灰蓝 `#e8ecf1 → #b8bcc5` | 深紫 55% | 暗灰深投影 | 否 |
| 按下 (`:active`) | 同默认 | 同默认 | 深度 -4px,投影压扁 | — |

灰态同时触发 `.draw-btn-wrap` 的 `.is-disabled`,关闭外扩光圈动画,
避免灰按钮有金色光圈违和。

次要按钮 "Tarik Lagi" 灰态(`.is-disabled-outline`):
- 背景 `rgba(255,255,255,.05)`,边框 15% 金
- 文字 35% 金
- 文案换成 "Besok 21:00"

## 每日 21:00 开放规则

按钮有三个阶段:

```
< 21:00                   按钮灰态 · "DIBUKA JAM 21:00 · HH:MM:SS" · 倒计时实时刷新
≥ 21:00 且 次数 = 0       按钮灰态 · "AJAK 3 TEMAN UNTUK DAPAT TARIKAN"
≥ 21:00 且 次数 > 0       按钮金色 · "BUKA SEKARANG · Nx" · 可连抽直到次数耗尽
```

顶部副倒计时的文案也会联动:

```
locked-before-21  →  "Dibuka dalam HH:MM:SS"
no-chances        →  "Butuh tarikan HH:MM:SS"
available         →  "Event aktif sekarang HH:MM:SS"(指下一个 21:00)
```

点到灰态按钮时弹 Toast:

- locked-before-21 → `⏰ Event dibuka jam 21:00 setiap hari`
- no-chances → `🎯 Ajak 3 teman untuk dapat kesempatan tarik`

## 两阶段任务 + 抽奖次数

**任务卡片按阶段切换视觉**:

| 阶段 | 奖励徽章 | 徽章色 | 副文案 |
|---|---|---|---|
| Phase 1(未完成) | `+10 KOIN` | 金色 | "Misi 1× saja. Setelah selesai dapat kesempatan tarik." |
| Phase 2(已完成 Phase 1) | `+1 TARIK` | 粉红色 | "Tiap 3 teman Lv.2: +1 Tarikan" |

Phase 2 时进度条下方额外显示 `· Total Nx`,展示累计获得的抽奖次数。

**抽奖次数 Chip**:

当 `drawChances > 0` 且未处于 revealed 状态时,按钮上方显示一个小 chip:

```
● 3x  Kesempatan Tarik Siap   (21:00 后可用)
● 3x  Siap dibuka jam 21:00   (21:00 前等待)
```

视觉细节:
- 胶囊圆角,金粉红渐变背景 `rgba(255,196,95,.22) → rgba(255,63,110,.14)`
- 左侧金色小圆点 1.2s 闪烁
- 次数用 Bebas Neue 18px,显眼
- 出现时 0.4s cubic-bezier 弹跳

**按钮文案总表**:

| 状态 | 主按钮 | 次要按钮 (Tarik Lagi) |
|---|---|---|
| 21:00 前 | `DIBUKA JAM 21:00 · HH:MM:SS` (灰) | `Ajak teman untuk tarikan` (灰) |
| 21:00 后,0 次 | `AJAK 3 TEMAN UNTUK DAPAT TARIKAN` (灰) | 同上 |
| 21:00 后,N 次 | `BUKA SEKARANG · Nx` (金) | `Tarik Lagi · Nx` (金) |

---

## Grand Prize 展示

奖池卡片底部通过虚线分割,展示一行 Grand Prize:

```
──────────────────────────────────
● GRAND PRIZE  [🪙] 4,280   untuk satu pemenang
```

- 左侧红色小圆点 + "GRAND PRIZE" 1.5px 字间距标签
- 中间 Bebas Neue 16px 金色数字,前面小金币图标
- 右侧 9.5px 斜体灰色提示"untuk satu pemenang di akhir event"
- 小圆点 1.2s 脉冲闪烁,和 LIVE 标签的节奏一样

数字会跟随所有用户的抽奖事件增长(每笔抽奖的 5%),具有社会证明效应。

## 规则弹窗(Aturan Modal)

触发:点顶部右上角 "Aturan ›" 按钮

样式:底部上滑 bottom-sheet,背景模糊 6px,最大高度 82%

6 条规则列表:
1. 邀请 3 个 Lv.2 好友得 10 Koin(一次性)
2. 之后每 3 个 Lv.2 好友 +1 抽奖机会(可重复)
3. 每天 21:00 开放抽奖
4. 抽奖金额 5-15 随机
5. 每次抽奖的 5% 入 Grand Prize,活动末抽一名幸运儿独得
6. 凡参与者都有机会中 Grand Prize

每条左侧带金色圆形编号 chip,右侧加粗关键字为金色。

底部主按钮 "Mengerti"(我知道了),点击关闭弹窗。
点遮罩区域也会关闭。

---

## 交互细节

- **触觉反馈**:支持 `navigator.vibrate` 的设备在 Draw 和 Reveal 时震动
- **防误触**:Draw 过程中按钮 `pointer-events: none`,同时状态机锁住
- **复制链接**:优先用 `navigator.clipboard`,降级到 `execCommand('copy')`
- **Toast 重叠**:同时只显示一条,后来的覆盖前面的(重启动画)
- **Safe area**:底部用 `env(safe-area-inset-bottom)` 适配全面屏
- **Reduced motion**:`prefers-reduced-motion: reduce` 关闭所有循环动画

---

## 视觉 QA 检查单

过审时请确认以下点在真机上一致:

- [ ] 背景光芒在慢速旋转
- [ ] 宝箱有 3s 呼吸上下浮动
- [ ] 奖池数字每 3-4 秒 +10 并有绿色浮字
- [ ] 任务进度槽位填充有弹跳动画
- [ ] 点 BUKA SEKARANG 后先抖动 1.8s 才开奖
- [ ] 开奖后金币从中心爆开到四周,不是直线
- [ ] 彩纸是 50 片向下飘(不是向上)
- [ ] 中奖数字从 0 缓动到结果,不是直接显示
- [ ] Actions 两个按钮有 300ms 延迟后滑入
- [ ] Toast 出现和消失都有缩放
- [ ] 任务完成后 task-card 变绿,+10 badge 变绿
- [ ] iPhone 刘海/胶囊区不被顶部内容遮挡
- [ ] Home Indicator 区域(底部)不被按钮压住
- [ ] 21:00 前按钮是灰白不可点,显示倒计时文案
- [ ] 21:00 整点时按钮自动切回金色可点(无需刷新)
- [ ] 次数 = 0 时按钮是灰白 "AJAK 3 TEMAN..." 文案,即便 21:00 后
- [ ] Phase 1 完成后任务卡切换到粉红"+1 TARIK"徽章,进度重置到 0/3
- [ ] Phase 2 每完成一轮 3/3,抽奖次数 +1,任务重置继续
- [ ] 抽奖次数 > 0 时按钮上方出现金粉渐变 chip 显示 "Nx 次数"
- [ ] 每次抽奖消耗 1 次,次数减 1,可连抽直到耗尽
- [ ] 刷新页面后任务进度和抽奖次数保持(localStorage 兜底)
- [ ] 用 `?state=locked|available|no-chances` URL 参数可预览三种按钮状态
