UI-UX/docs/design-spec.md
iye d5ed43acbd feat(ui): design overhaul, global login modal, design spec
- nav: center links (首页/排行榜/我的), right-side AuthMenu + RemainingVotesBadge; image logo with responsive sizing
- auth: replace /login route with global LoginModal triggered anywhere; "我的" intercepts unauth users with post-login redirect
- home: full-screen Hero, redesigned Top12 (12 pill cards, top-3 glow), scroll-snap mandatory between Hero/Top12/candidates
- home: candidates section with sticky filter that gains frosted-glass bg when stuck (matches nav)
- filter: simplified tags (全部/舞蹈/声乐/rap/全能型); ArtistCard uniform purple vote button
- ranking/me: remove Top12Bar; me header stacks 编辑资料/退出登录 vertically
- typography: font-logo set to Orbitron; ✦ glyph in CYBER ✦ STAR preserved
- layout: max-w-[1500px] unified across pages
- docs: add design-spec.md + design-spec.html with full visual spec (lucide SVG, zero emoji policy)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 18:59:30 +08:00

605 lines
24 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CYBER STAR · 视觉设计规范 v2
> 适用范围CYBER STAR 虚拟偶像 Top12 出道企划官网(首页、排行榜、艺人详情页、个人中心)
> 设计语言:**赛博 / 暗黑 / 紫色霓虹 / 太空感**
> 更新时间2026-05-12
---
## 1. 品牌识别
### 1.1 Logo
- **主 Logo**:金属铬质 `CYBER STAR` 文字 + 右侧星形装饰PNG 透明背景)
- 路径:`/public/logo.png`(待放置)
- 原始比例:约 **2.7 : 1**
- 最小展示宽度:**120px**
- 顶栏使用高度:**32px**,对应宽度约 **86px**
- **简化 Logofavicon / 极窄场景)**:紫色四角星 SVG自定义 path 或 lucide `Sparkles`),单独使用时配紫色辉光
### 1.2 关键词
赛博朋克、未来感、神秘、紫色霓虹、深空、半透明、辉光、玻璃质感glassmorphism
### 1.3 不要做的事
- **禁止**:不使用扁平色块大面积铺底
- **禁止**:不使用强烈的彩虹色 / 多色对比
- **禁止**:不使用阳光、暖色调
- **禁止**:不使用粗线条 / 卡通风格的图标
---
## 2. 色彩系统
### 2.1 背景层级(暗紫调)
| Token | HEX | 用法 |
|---|---|---|
| `--color-deepest` | `#08051A` | 页面最底层背景 |
| `--color-deep` | `#0D0A24` | 导航 / Footer 背景 |
| `--color-base` | `#13102E` | 主要区块背景 |
| `--color-surface` | `#1A1638` | 一级卡片 / 输入框 |
| `--color-elevated` | `#221D4A` | 浮层 / 弹窗 / Hover 态 |
| `--color-card` | `#1E1840` | 艺人卡片底色 |
> 视觉策略:层级越深、颜色越亮一点点,营造空间纵深感。
### 2.2 主调紫 · Royal Violet
| Token | HEX | 用法 |
|---|---|---|
| `--color-purple-100` | `#EDE9FE` | 极淡紫,几乎不用 |
| `--color-purple-200` | `#DDD6FE` | 高亮文字 |
| `--color-purple-300` | `#C4B5FD` | **主要文字高亮 / 标题点缀** |
| `--color-purple-400` | `#A78BFA` | 边框 / 图标 / 次级按钮文字 |
| `--color-purple-500` | `#8B5CF6` | **主品牌色**,按钮、徽章 |
| `--color-purple-600` | `#7C3AED` | 按钮 hover / 强调 |
| `--color-purple-700` | `#6D28D9` | 按钮 active / 渐变深端 |
| `--color-purple-800` | `#5B21B6` | 极深紫,渐变深端 |
### 2.3 文字颜色
| 用途 | 值 | 备注 |
|---|---|---|
| 主标题 / 强调 | `#FFFFFF` (white) | 100% 不透明 |
| 正文 | `rgba(255,255,255,0.85)` | 二级阅读文字 |
| 次要说明 | `rgba(255,255,255,0.65)` | slogan / placeholder |
| 弱化 | `rgba(255,255,255,0.45)` | 元数据 / 提示 |
| 几近隐藏 | `rgba(255,255,255,0.25)` | disabled 文字 |
| 紫色强调 | `var(--color-purple-300)` | 票数 / 标签 / 排名 |
| 错误 | `var(--color-pink-500)` `#EC4899` | 限警告类文案 |
### 2.4 边框
| Token | 值 | 用法 |
|---|---|---|
| `--border-subtle` | `rgba(255,255,255,0.08)` | 默认分隔 |
| `--border-default` | `rgba(255,255,255,0.14)` | 卡片 / 输入框边框 |
| `--border-purple` | `rgba(139,92,246,0.55)` | 强调态边框 |
| `--border-glow` | `rgba(196,181,253,0.65)` | 辉光边框 |
### 2.5 渐变
| Token | 用法 |
|---|---|
| `--grad-hero` | Hero 区放射状暗紫Hero 视频缺失时的降级背景 |
| `--grad-purple` | 主按钮渐变135°深紫 → 中紫 → 浅紫) |
| `--grad-purple-deep` | 深沉版主渐变 |
| `--grad-card` | 艺人卡片背景155°elevated → surface |
| `--grad-violet-glow` | 放射状辉光,装饰用 |
| `--grad-shine` | 按钮微光扫过效果 |
### 2.6 辅助色(仅限点缀)
| 名 | HEX | 限定场景 |
|---|---|---|
| Cyan-400 | `#38D9F5` | 数据点缀、统计强调,不用作大面积 |
| Blue-500 | `#2D7FFF` | 链接 hover不用作背景 |
| Magenta | `#D946EF` | 特殊状态 |
| Pink-500 | `#EC4899` | 错误、警示 |
> Token 中保留的 `--color-gold-400` / `--color-silver` / `--color-bronze` **当前不使用**,预留给后续可能的徽章升级;本规范及当前设计稿只用紫色统一表达排名层级。
---
## 3. 字体系统
### 3.1 字体族
| 用途 | 字体 | Fallback |
|---|---|---|
| **`font-logo`** | **Orbitron**500 / 700 / 900 | Audiowide, sans-serif |
| **`font-display`** | Audiowide | sans-serif |
| **`font-label`**(英文标签全大写) | Cinzel | serif |
| **`font-body`**(中英文正文) | Inter | Source Han Sans SC, PingFang SC, Microsoft YaHei |
> 中文一律使用 `font-body`,不要尝试用 display 字体显示中文(不支持字形)。
### 3.2 字号阶梯
| 用途 | 桌面尺寸 | 移动尺寸 | tracking |
|---|---|---|---|
| Hero 主标题 H1 | `clamp(64px, 7vw, 96px)` | 48px | `0.35em` |
| 区块标题 H2 | 18px | 16px | `0.2em` |
| 卡片标题 | 14px | 13px | normal |
| 正文 | 14px | 13px | normal |
| 标签 / Eyebrowuppercase | 11px | 10px | `0.3em ~ 0.4em` |
| 数字(票数 / 排名) | 用 `tabular-nums` | — | normal |
### 3.3 排版规则
- 英文 uppercase + tracking 是品牌核心调性,**所有英文 label 必须大写 + 字间距 ≥ 0.2em**
- 中文不强制全大写、不强制字间距
- 行高:标题 1.1-1.2,正文 1.6
- 数字必须 `tabular-nums`(票数对齐)
---
## 4. 间距 & 布局
### 4.1 基础栅格
- 间距基数:**4px**
- 常用间距:`4 / 8 / 12 / 16 / 20 / 24 / 32 / 40 / 64`
### 4.2 容器
| 元素 | 值 |
|---|---|
| Page max-width | `1280px``max-w-7xl` |
| 水平 padding移动 | 16px |
| 水平 padding桌面 | 32px |
| Section 之间纵向间距 | 桌面 64px / 移动 40px |
### 4.3 艺人卡片网格
| 断点 | 列数 | gap |
|---|---|---|
| `< 640px` | 2 | 12px |
| `≥ 640px` | 3 | 16px |
| `≥ 768px` | 4 | 16px |
| `≥ 1024px` | **5** | 16px |
### 4.4 Top12 头像横排
- 头像直径:`64-72px`(响应式)
- 头像间距12-16px
- 单行铺满,不允许换行;移动端横向滚动
---
## 5. 圆角 & 阴影 & 辉光
### 5.1 圆角
| 用途 | 值 |
|---|---|
| 小标签 / Pill | `9999px`(完全圆) |
| 小元素(徽章) | `9999px`(圆) |
| 输入框 / 小按钮 | `8px` |
| 卡片 / 容器 | `12px` |
| 大卡片 / 弹窗 | `16-20px` |
| Hero 区 | `20-24px` |
### 5.2 阴影
| Token | 值 | 用法 |
|---|---|---|
| `--shadow-card` | `0 8px 32px rgba(0,0,0,0.65)` | 卡片默认 |
| `--shadow-purple` | `0 0 24px rgba(139,92,246,0.5), 0 0 60px rgba(139,92,246,0.18)` | 紫色辉光(按钮 / 选中态) |
| `--shadow-glow` | `0 0 40px rgba(196,181,253,0.25)` | 高光氛围 |
### 5.3 文字辉光
```css
.glow-text-purple {
text-shadow:
0 0 16px rgba(196, 181, 253, 0.55),
0 0 32px rgba(139, 92, 246, 0.35);
}
```
仅用于Hero 主标题、激活态导航项。
---
## 6. 动效规范
| 名称 | 时长 | Easing | 用法 |
|---|---|---|---|
| Hover 微抬升 | `200ms` | `ease-out` | 卡片 `translateY(-2px)` |
| 按钮渐变 | `180ms` | `ease-out` | 颜色 / 阴影变化 |
| 弹窗进入 | `280ms` | `cubic-bezier(0.22, 1, 0.36, 1)` | scale 0.94→1 + opacity |
| 弹窗退出 | `200ms` | `ease-in` | scale 1→0.96 + opacity |
| `pulse-glow` | `2.4s` infinite | `ease-in-out` | VOTE 按钮 / 当前排名 |
| `float` | `3s` infinite | `ease-in-out` | 滚动提示 / 装饰 |
| `spin-slow` | `20s` infinite | `linear` | Hero 装饰光环 |
---
## 7. 组件规范
### 7.1 导航栏Navigation
```
┌──────────────────────────────────────────────────────────┐
│ [LOGO] 首页 排行榜 [Search] [登录/注册] │
└──────────────────────────────────────────────────────────┘
```
> 示意图中 `[Search]` 表示 lucide `Search` SVG 图标36×36 圆形按钮),代码实现绝不使用搜索 emoji。
| 属性 | 值 |
|---|---|
| 高度 | `64px` |
| 背景 | `rgba(13,10,36,0.85)` + `backdrop-blur(xl)` |
| 底边 | `1px solid rgba(255,255,255,0.08)` |
| 行为 | `sticky top-0`z-index 50 |
| Logo | 高度 32px |
| 导航项间距 | 32px |
| 导航项字体 | `font-display`、12px、`tracking-[0.25em]`、uppercase |
| 默认色 | `rgba(255,255,255,0.65)` |
| 激活色 | `var(--color-purple-300)` + `.glow-text-purple` + 底部 1px 紫线 |
| 搜索图标 | 36×36 圆形按钮,`rgba(255,255,255,0.04)` 背景 |
| 登录按钮 | 36 高度紫色描边胶囊padding-x 20px |
> **注意**:倒计时**不放在导航栏**,仍保留在 Hero 内。
### 7.2 Hero 区(全屏视频背景)
```
┌─────────────────────────────────────────────┐
│ TOP 12 VIRTUAL IDOL DEBUT PROJECT │
│ ┌────────────────┐ │
│ │ 距离投票结束 │ │ ← 浅紫边框胶囊
│ │ 12天 03:24:16 │ │
│ └────────────────┘ │
│ CYBER ✦ STAR │
│ │
│ 虚拟偶像出道企划 │
│ │
│ [VolumeX] │ ← 仅声音按钮
└─────────────────────────────────────────────┘
```
| 属性 | 值 |
|---|---|
| 高度 | `70vh`(最小 480px / 最大 720px |
| 圆角 | `20px` |
| 背景 | 全屏视频 `object-cover` + 半透明黑色蒙层 |
| 视频行为 | `autoPlay` `loop` `muted` `playsInline` |
| 蒙层 | 顶部 45% 黑 → 中部 15% 黑 → 底部 75% 黑(垂直渐变) |
| **禁止****Hero 内不放任何按钮** | 删除 "Play Debut PV"、删除左上 "Debut PV 自动播放" tag |
| 倒计时位置 | **右上角**,距边 24px |
| 倒计时容器 | `padding: 8px 16px` + **`1px solid rgba(196,181,253,0.4)` 浅紫边框** + `rounded-full` 胶囊 + `rgba(13,10,36,0.55)` 半透明深紫底 + `backdrop-blur` |
| 倒计时文字 | 12-13px 白字 + 紫色高亮数字 + `tabular-nums` |
| 声音按钮位置 | **右下角**,距边 20px |
| 声音按钮 | 36×36 圆形 / `rgba(0,0,0,0.55)` + `backdrop-blur` + 白色 `Volume2` / `VolumeX` SVGlucide-react |
| 视频缺失降级 | 用 `--grad-hero` 渐变填充 |
### 7.3 Top 12 出道位
```
┌───────────────────────────────────────────────┐
│ [Trophy] 实时 Top12 出道位 查看完整榜单 [→] │
│ │
│ (o)(o)(o)(o)(o)(o)(o)(o)(o)(o)(o)(o) │ ← 圆形头像
│ 1 2 3 4 5 6 7 8 9 10 11 12 │ ← 紫色序号圆
│ 艺人 A 艺人 B … │
│ 12.6W 票 … │
└───────────────────────────────────────────────┘
```
> 示意图中 `[Trophy]` `[→]` 表示 lucide `Trophy` `ChevronRight` SVG绝不使用奖杯 emoji。
| 元素 | 规范 |
|---|---|
| 容器 | `rgba(13,10,36,0.95)` + `border-subtle` + `rounded-xl` + padding 16px |
| 头像 | **圆形**,直径 64-72px2px 紫色边框(`--color-purple-500`),紫色辉光 |
| 序号徽章 | 独立的、头像下方居中、紫色实心圆、20×20、白字数字 |
| 名字 | 12px、白色、居中、单行省略 |
| 票数 | 11px、`--color-purple-300`、居中、`tabular-nums` |
| 全部 12 位 | 统一紫色边框 + 紫色辉光,**不区分 1-3 / 4-12** |
| 移动端 | 横向滚动 + snap |
| 禁止 | **不要再加 VOTE NOW 侧栏** |
### 7.4 筛选 + 搜索栏
```
┌───────────────────────────────────────────────────┐
│ 全部 舞蹈担当 声乐担当 rap担当 全能型 [Sort] [Search][G/L]│
└───────────────────────────────────────────────────┘
```
> `[Sort]` = lucide `ArrowUpDown`、`[Search]` = lucide `Search`、`[G/L]` = lucide `LayoutGrid` + `List` SVG视图切换
| 元素 | 规范 |
|---|---|
| 标签按钮 | 文字 only、无边框、padding 6px 12px、12px |
| 默认色 | `rgba(255,255,255,0.55)` |
| Hover | `rgba(255,255,255,0.85)` |
| 激活 | `--color-purple-300` + 底部 2px 紫线 |
| 排序触发 | 12px、含图标、`rgba(255,255,255,0.04)` 背景 |
| 搜索框 | 高度 36、`--color-surface` 背景、左侧搜索图标、placeholder 45% 白 |
| 视图切换 | 36×36 双按钮组、激活态 `--color-purple-500/12` 紫色背景 |
#### 标签筛选(固定 5 项 · 不可改)
| 标签 key | 中文文案 | 默认筛选行为 |
|---|---|---|
| `all` | 全部 | 显示全部 35 位(默认激活态) |
| `dance` | 舞蹈担当 | 筛选 `tags``dance` 的艺人 |
| `vocal` | 声乐担当 | 筛选 `tags``vocal` 的艺人 |
| `rap` | rap担当 | 筛选 `tags``rap` 的艺人(注意:小写 rap无空格 |
| `all-rounder` | 全能型 | 筛选 `tags``all-rounder` 的艺人 |
> 移除 `visual` `leader` 等其它标签的筛选入口(数据可保留,但不在筛选栏暴露)。
### 7.5 艺人卡片(关键组件)
```
┌─────────────────┐
│ (1) │ ← 紫色圆形排名徽章(左上)
│ │
│ [立绘 4:5] │
│ │
├─────────────────┤ ← 信息区与立绘明确分隔
│ No.001 │
│ 艺人 A │
│ 樱花校园系 │
│ [♥] 12.5w 票 │ ← [♥] = lucide Heart SVG
│ │
│ ┌─────────────┐ │
│ │ 投票 │ │ ← 紫色实心、占满整行
│ └─────────────┘ │
└─────────────────┘
```
#### 通用规范
| 元素 | 规范 |
|---|---|
| 圆角 | `12px` |
| 背景 | `var(--grad-card)` |
| 立绘 | `aspect-[4/5]`object-cover |
| 立绘 / 信息分隔 | 1px 顶部 `border-subtle` + 信息区底色 `rgba(0,0,0,0.4)` 叠加 |
| Padding信息区 | 12px |
| 编号 No.xxx | 11px、`rgba(255,255,255,0.55)``font-display` |
| 艺人名 | 14px、白色、`font-semibold`、truncate |
| Slogan | 11px、`rgba(255,255,255,0.55)`、truncate |
| Heart SVG + 票数 | 12px、`--color-purple-300``font-display``tabular-nums`(图标用 lucide `Heart` size=12**禁用心形 emoji** |
| 排名徽章 | 28×28 圆形、`--color-purple-500` 实心、白字 14px、`shadow-purple-glow`、左上 distance 8px |
#### 投票按钮(所有排名统一样式)
| 属性 | 值 |
|---|---|
| 高度 | 36px |
| 圆角 | 8px |
| 文案 | **「投票」**(中文,不是 "Vote" |
| 样式 | `--grad-purple` 实心 + 白字 + 紫色辉光(`shadow-[0_0_12px_rgba(139,92,246,0.35)]` |
| Hover | `brightness(1.1)` + 更强辉光 |
| Active | `brightness(0.95)` |
> **注意****所有 35 张卡片的投票按钮完全相同**,不因排名 Top12 / 13+ 而变样式。
#### 排名差异化(严格按设计稿:二档制)
仅通过 **2 个**变量差异化,不动按钮:
| 排名段 | 立绘 | 边框 + 辉光 | 排名徽章 | 投票按钮 |
|---|---|---|---|---|
| **Top 1-12出道位** | 鲜艳(`opacity 1` | `--border-purple` 紫边 + `--shadow-purple` 紫辉光 | 紫色实心圆 + 紫色辉光 | **紫色实心**(同下行) |
| **13+(候选区)** | 轻度暗化(`opacity 0.78` | 14% 白边框 + **无**辉光 | 暗色徽章(`--color-elevated` 底 + 55% 白字) | **紫色实心**(与上行**完全相同** |
> 卡片结构 100% 一致,便于复用同一 React 组件,仅通过 `inTop12` 布尔变量控制立绘 opacity + 边框样式 + 徽章样式三处。
### 7.6 Footer
```
© 2026 CYBER STAR · All Rights Reserved
```
| 属性 | 值 |
|---|---|
| 高度 | 64px |
| 背景 | `--color-deep` |
| 文字 | 11px、`rgba(255,255,255,0.35)`、居中 |
| 不放链接 | 极简化 |
### 7.7 按钮(通用)
| 变体 | 用途 | 样式 |
|---|---|---|
| Primary | 主操作(投票、确认) | `--grad-purple` + 白字 + `--shadow-purple` |
| Outline | 次操作(登录、注册) | 透明背景 + `--border-purple` 边框 + 紫色文字 |
| Ghost | 工具栏(搜索、关闭) | 5% 白背景 + 14% 白边框 + 70% 白文字 |
| Danger | 退出登录 | `--color-pink-500` + 白字 |
| 尺寸 | 高度 | padding-x | font-size |
|---|---|---|---|
| sm | 32 | 14 | 10 |
| md | 44 | 24 | 12 |
| lg | 56 | 40 | 14 |
### 7.8 弹窗 / 遮罩层
| 属性 | 值 |
|---|---|
| 遮罩 | `rgba(0,0,0,0.75)` + `backdrop-blur(md)` |
| 弹窗容器 | `--color-elevated` 95% 透明度 + `border-default` + `rounded-2xl` |
| 阴影 | `0 24px 80px rgba(0,0,0,0.7), 0 0 40px rgba(139,92,246,0.12)` |
| **禁止**:顶部光条 | **删除**(不要 2px 紫色横条,保持容器干净) |
| 关闭按钮 | 右上角 24×24lucide `X` SVG55% 白色 |
| 居中 | `position:fixed``inset:0``flex items-center justify-center` |
| z-index | 100 |
---
## 8. 图标 & 装饰
### 8.1 图标库(铁律)
- **禁止****严禁使用任何 emoji**(包括奖杯、心形、放大镜、喇叭、播放三角、上下箭头等所有彩色 / Unicode 装饰字符)
- **唯一例外**`CYBER ✦ STAR` 品牌字标中间的 `✦`U+2726保留原字符使用
- **使用****统一使用 `lucide-react`**线条风、stroke 1.5-2
- 严禁混用 filled / outlined / cartoon icons
- 标准尺寸12 / 14 / 16 / 20 / 24
### 8.2 场景对应的 lucide 图标
| 场景 | lucide 组件名 | 备注 |
|---|---|---|
| 票数前缀 | `Heart` | `fill="currentColor"` 实心;颜色 `--color-purple-300` |
| Top12 榜单标题 | `Trophy` | 紫色 stroke |
| 标题装饰星 | `Sparkles` 或自定义 `<svg>` | 四角星形 |
| 查看更多链接 | `ChevronRight` | 12-14px |
| 搜索 | `Search` | 16-18px |
| 静音 / 取消静音 | `VolumeX` / `Volume2` | 14-16px |
| 视图切换 | `LayoutGrid` / `List` | 16px |
| 排序 | `ArrowUpDown` | 14px |
| 弹窗关闭 | `X` | 18px |
| 加载中 | `Loader2` + `animate-spin` | 14-16px |
| 投票心形(按钮内) | `Heart` | 14px按钮内置 |
| 播放(仅艺人详情视频用) | `Play` `Pause` | Hero 内不使用 |
### 8.3 装饰符号(仅以 SVG 形式出现)
- **CYBER STAR 中间的 ✦**:使用原 `✦` 字符Unicode U+2726 BLACK FOUR POINTED STAR作为装饰配合紫色辉光。这是品牌字标的一部分**是 §8.1 emoji 禁令的唯一例外**
- **页面装饰光斑 / 粒子**:通过 `body::before` `body::after``radial-gradient` 实现,不引入额外图标
### 8.4 环境装饰层
`body::before` 提供低饱和紫色雾光(左上、右下双焦点),`body::after` 提供 8 个静态星点。**不要在内容区单独添加大面积装饰光斑**,避免视觉拥挤。
---
## 9. 响应式断点
| 断点 | 设备 | 行为 |
|---|---|---|
| `< 640px` | 手机 | 单列 / 双列卡片、横滚 Top12、隐藏 nav 文字 |
| `≥ 640px` | 大手机 / 平板竖 | 3 列卡片 |
| `≥ 768px` | 平板横 | 4 列卡片nav 文字显示 |
| `≥ 1024px` | 桌面 | **5 列卡片**,完整布局 |
| `≥ 1280px` | 大桌面 | 容器 `max-w-7xl` 居中 |
---
## 10. 通用 UI/UX 网页设计规范(必须遵守)
### 10.1 可访问性WCAG 2.1 AA
- 所有交互元素必须有 `aria-label` 或可见文字
- **颜色对比度**:正文文字与背景 ≥ 4.5:1大号文字 ≥ 3:1
- 紫色辉光按钮文字必须保持白色不透明,不要降到半透明
- 不依赖颜色单独传达信息(必须配合图标 / 文字)
- 视频自动播放必须 `muted`,并提供解除静音控件
- 弹窗Escape 关闭、聚焦陷阱focus trap`aria-modal="true"`、关闭后焦点归还触发元素
### 10.2 焦点指示Keyboard Navigation
- **所有可聚焦元素**(按钮、链接、输入框、卡片)必须有可见 `:focus-visible` 轮廓
- 标准2px 紫色实线 + 2px 偏移,颜色 `var(--color-purple-400)`
- 不要使用 `outline: none` 而不提供替代焦点样式
- Tab 顺序遵循视觉顺序(左→右、上→下)
### 10.3 触控目标Touch Target
- 移动端最小触控目标 **44 × 44 px**iOS HIG/ 48 × 48 dpMaterial
- 相邻可点击元素之间至少留 **8px** 间距
- 卡片整体可点(跳详情)+ 内部投票按钮独立可点 → 必须用 `event.preventDefault` + `stopPropagation` 隔离
### 10.4 加载与反馈状态Loading / Empty / Error
每个数据展示组件**必须**实现以下三态:
| 状态 | 视觉 |
|---|---|
| **加载中Loading** | 骨架屏skeleton— 紫灰渐变占位,**不**用 spinner 占整页 |
| **空状态Empty** | 居中插画 / 图标 + 一句说明文字 + 可选行动按钮 |
| **错误Error** | 居中错误图标pink-500+ 描述 + 「重试」按钮 |
异步操作(投票、登录):
- 触发后立即在按钮内显示 loading spinner按钮 `disabled` 防重复
- 成功 / 失败用 `react-hot-toast` 全局 toast 反馈,**不**用 alert / confirm
### 10.5 表单设计
- Label 始终在输入框**上方**(不用浮动 label避免遮挡
- 错误提示:输入框下方红色文字 + 边框转 `pink-500`
- Placeholder 不能代替 label仅给示例
- 必填字段标 `*`(紫色)
- 按钮文案说明动作而非"提交"(如「立即登录」「发送验证码」)
### 10.6 链接与按钮的语义区分
| 元素 | 用途 | 视觉 |
|---|---|---|
| `<button>` | 触发动作(投票、打开弹窗、提交) | 实心 / 描边 / Ghost |
| `<a href>` | 跳转页面(详情页、外链) | 文字 + hover 下划线 |
**禁止**:用按钮做跳转 / 用链接做表单提交。
### 10.7 信息密度与留白
- 同一区块内最多 **3 个**字号层级
- 每个 section 之间纵向留白 ≥ 40px移动/ 64px桌面
- 卡片内部 padding 不小于 12px
- 文字段落最大宽度 ≤ 75 字符(避免长行难读)
### 10.8 文案与本地化
- 中文用中文标点(。,!?:"
- 英文 label 全大写 + tracking
- 数字千位分隔12,650 / 12.6W
- 时间用相对时间("3 分钟前"+ tooltip 显示绝对时间
- 长文本截断必须用 `...` 并在 hover 提供 tooltip
### 10.9 性能预期
- LCP < 2.5sHero 视频懒加载poster 先显示
- CLS < 0.1所有图片 / 视频留好 aspect-ratio 占位
- 卡片立绘必须 `width / height` 属性或 `aspect-ratio` 防回流
### 10.10 暗色模式专属规则
- **禁止纯黑 #000** `#08051A` 作为最深色避免 OLED 屏闪烁感
- **禁止纯白 #FFF 大面积**白文字用白背景**不用**
- 阴影改为辉光box-shadow with color传统黑色阴影在暗色背景不可见
- 图片 / 视频缩略图加 4% 白色 overlay避免在暗背景"漂浮"
---
## 11. 内容文案约定
| 场景 | 文案 |
|---|---|
| 投票按钮 | **投票」**不用 "Vote" |
| 顶部 nav | 首页」「排行榜 |
| 标签筛选 | 全部」「舞蹈担当」「声乐担当」「rap担当」「全能型」(rap 小写无空格 |
| 排名榜标题 | `<Trophy size={14}/>` + 实时 Top12 出道位 |
| 倒计时前缀 | 距离投票结束 |
| 投票成功 | 已为 {名字} 投出 {N} |
| 票数耗尽 | 今日票数已用完明天再来吧 |
| 卡片票数 | `<Heart size={12} fill="currentColor"/>` + 12.6W 」(W 大写)。**禁用心形 emoji** |
| 版权 | 「© {当年} CYBER STAR · All Rights Reserved |
---
## 12. 设计稿与代码 token 映射表(交付辅助)
| Figma 颜色名 | CSS 变量 | Tailwind 工具类 |
|---|---|---|
| Background / Deepest | `var(--color-deepest)` | `bg-deepest` |
| Background / Card | `var(--color-card)` | `bg-card` |
| Brand / Purple 500 | `var(--color-purple-500)` | `bg-purple-500` `text-purple-500` |
| Brand / Purple 300 | `var(--color-purple-300)` | `text-purple-300` |
| Border / Subtle | `var(--border-subtle)` | `border-white/[0.08]` |
| Shadow / Purple Glow | `var(--shadow-purple)` | `shadow-purple-glow` |
| Gradient / Purple | `var(--grad-purple)` | `bg-grad-purple` |
> 设计师交付时**直接引用 Tailwind 工具类名**,开发可零成本接入。