调研日期:2026-10-14 | 产出用途:给老板改徽章代码用 结论都在文末「D」节,D 节每个参数都能直接贴进 演示站-en/assets/styles.css。 每条结论后面都带链接;找不到公开资料的写「未找到公开资料」,没有编造。
---
代码位置:演示站-en/assets/styles.css
| 项 | 现状 |
|---|---|
| 形状 | .hbhex / .hexbadge:尖顶六边形,clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%) |
| 尺寸 | 34×38(默认)、24×27(.sm) |
| 层次 | 底色 tint(::before,opacity .22→.32)、.hbfill(径向 + 线性双渐变)、.hbico 图标、.hbnum 数字、.hbglow 呼吸光晕 |
| 动效 | .hbrim::before:conic-gradient(from 0deg, transparent 0deg 280deg, var(--hb-shine) 320deg, transparent 360deg),被 evenodd 双路径 mask 切成 1px 边环,hover 时 animation: .3s linear hbRimShine(rotate -1turn);.on 钉住时 1.6s linear infinite |
pools-clone-deploy/assets/root-D9nZBKc8.css 提取)| 项 | pools.trade 实际值 |
|---|---|
| 形状 | .pools-badge-hex:平顶圆角六边形,36×36,clip-path: path(),圆角 r=6(=宽度 16.7%) |
| 层次结构 | .pools-badge-hex(外形)→ .pools-badge-hex-fill(内缩 1px 的第二条 path,做 1px 边)→ .pools-badge-rim(evenodd mask 出边环)→ .pools-badge-glow(径向光晕)→ .pools-badge-base 单色主题变量 |
| 边环 mask | SVG fill-rule="evenodd" 双路径,外 36 内 35 → 1px 边 |
| conic 参数 | conic-gradient(from 0deg, transparent 0deg 280deg, var(--pools-badge-base) 320deg, transparent 360deg),容器 inset:-30% |
| conic 动效 | hover:animation: .3s linear pools-badge-rim-shine(rotate -1turn)——一次性,300ms |
| 尺寸阶梯 | 32 / 36 / 112(compact / base / hero) |
| 呼吸 | .pools-badge-glow:pools-badge-breathe 4s |
我们抄的不是「conic-gradient」这个手法,而是抄了一整套参数组合:
transparent 0→280deg,shine 320deg,transparent 360deg.3s linear,同样的 rotate -1turn形状方向不同(我们尖顶、pools 平顶),颜色纪律不同(我们五色语义、pools 单色),但动效机制是逐项对照的复刻。
所以老板的担心是对的一半:手法通用不算抄(见 C 节),但"逐参数复刻 + 都在暗色加密产品里 + 都是六边形"这个组合,被同行一眼认出来是高概率事件。要改的是机制,不是颜色。
---
| 产品 | 形状 | 层次 | 尺寸阶梯 | 状态 | 配色纪律 | 出处 |
|---|---|---|---|---|---|---|
| OpenSea | 蓝色对勾(不是奖章) | 单色图标,无描边无底色,贴在名字/头像旁 | 跟随文字与头像(规范未公开) | verified account / badged collection 两态,没有稀有度 | 蓝 = 平台认证,不与稀有度混用 | OpenSea Help: What is a verified account or badged collection? / OpenSea Blog: We're Improving the OpenSea Verification Process |
| Blur | 未找到公开资料 | — | — | — | — | 无公开设计/帮助文档可引 |
| Magic Eden | 未公开(帮助中心只描述"给合集加徽章"的申请与审核流程) | — | — | 已加徽章 / 未加徽章 | 徽章 = 审核通过 | Magic Eden Help: How to Get Your NFT Collection Badged |
| Zora | 未公开(官方支持文只讲"如何验证个人资料") | — | — | verified / 未验证 | — | Zora Support: Verifying your profile |
| Farcaster / Warpcast | 未公开视觉规范;「Power Badge」公开的是数据口径(谁算 power user,阈值明确) | — | — | 有 / 无 Power Badge | — | Dune 数据目录:farcaster power_badge |
| Lens | 未找到公开资料的徽章视觉规范(官方文档只公开 Profile 数据接口) | — | — | — | — | Lens Docs: Get profiles |
| Coinbase / Base | 未找到公开资料:Coinbase 没有公开的设计系统站点;检索到的都是第三方分析页,不作为依据 | — | — | — | — | — |
可抄结论 1:加密产品的徽章几乎全是"认证 / 信任"语义,做法是单色、少而稳、不做稀有度。
可抄结论 2:它们普遍不公开视觉规范——所以"参考加密同行"这条路本身就没什么可抄的。我们做的是"成就",应该去游戏 / 健身 / 学习类产品抄(A.2)。
| 产品 | 形状 | 层次 | 尺寸阶梯 | 状态 / 分级 | 配色纪律 | 出处 |
|---|---|---|---|---|---|---|
| GitHub Achievements | 圆形奖章(我看了官方 changelog 配图:成就面板 10 枚圆形徽章,2 行 × 5 列) | 单枚徽章自带插画主体 + 左上角一道金属高光(银/金那两枚像金属币);无外描边、无统一底色;同一张图里 "STAFF" 用的是文字胶囊(小号大写、彩底白字)——说明 GitHub 对"身份标识"和"成就奖章"用两套形状 | profile 侧栏约 48px(配图量得,官方未公开数值) | 同一成就多个 tier,profile 只显示已获得的最高 tier;未获得不显示 | 每枚徽章自带一套配色(插画驱动),不共用语义色 | GitHub Changelog 2026-09-11: Profiles now show your highest achievement badge tier(配图即上表描述来源)/ 社区维护的完整清单(非官方):github-achievements、rezzcode/Github-Profile-Achievements |
| Discord | 未找到官方视觉规范;2025-07 上线的 Orbs 奖励系统用「徽章」作为任务奖励 | — | — | 任务完成得徽章 | — | 媒体报道(二手):Gigazine 2025-07-15 |
| Steam | 集换式卡牌合成的徽章,显示在个人资料;闪卡(foil)是稀有版本 | 徽章有等级(badge level),可升级 | 未公开设计数值 | 普通 / 闪卡 foil 双工艺,等级 1–5+ | 稀有度靠工艺(闪)区分,不靠换色 | Steamworks 文档:Steam Community Items / Steam 客服 FAQ:Trading Cards |
| Duolingo | 彩色插画徽章(角色出镜),非几何形 | 插画主体 + 名称 + 进度/条件;个人记录另成一组 | 未公开 | 有难度等级、稀有徽章(如连续一年)、个人记录(Personal Records) | 快乐、鲜艳、多色;官方品牌规范公开 | Duolingo Blog 2023-12-11:Start earning brand-new Achievements / Duolingo 品牌规范 design.duolingo.com |
| Strava | 挑战/活动完赛奖章(形状未公开) | — | — | 完赛即得,绑定具体挑战 | 品牌方可定制(官方提供挑战素材指南) | Strava Business:Creating assets for your sponsored challenge |
| Apple Fitness | 奖章式(Awards) | 按活动类型 + 里程碑颁发 | 未公开 | 达成即得 | 系统级统一视觉 | Apple 支持:See your activity history, trends, and awards in Fitness |
| Apple HIG / Game Center 成就 | 成就 = 徽章 + 进度,可设多等级 | — | — | 多等级 / 未解锁 | 官方 HIG 索引:成就用于"给玩家额外动力" | Apple HIG 总目录 / Game Center 章节(二手转录):hig-doctor/references/game-center.md |
| PlayStation Trophies | 奖杯 | — | — | 铜 / 银 / 金 / 白金四级,白金需集齐其他奖杯 | 层级名跨所有游戏统一 | PlayStation 官方支持:How to earn trophies |
| Xbox Achievements | 成就(含玩家分数) | — | — | 2026-09 起测试 Mythic Achievements(在现有层级之上再加最高稀有度) | 层级名统一 | Xbox Wire 2026-09-29 / Microsoft Learn:Achievement Title History URIs |
| Linear | 没有成就徽章体系;公开文档只定义 label 与 status 的语义与用法,未公开视觉规范。界面上标签是圆角胶囊、用色相区分分类(视觉细节以产品界面为准,未见官方规范页) | 底色 + 文字,无内发光、无描边堆叠 | 未公开 | 状态可自定义(Backlog / Todo / In Progress / Done / Canceled…) | 颜色属于分类,不用于表达"优先级高低"或稀有度;全站只有一种标签形状 | Linear Docs: Issue labels / Linear Docs: Issue status / The Linear Method(Figma Blog,含设计理念) |
可抄结论 3(最重要):成熟产品的稀有度不靠"换色相",靠工艺——Steam 用闪卡材质、GitHub 用金属高光、PS/Xbox 用统一层级名。这正好解决我们"只有五色、却想表达 5 个稀有度"的死结(方案见 D.4)。
可抄结论 4:GitHub 把"身份标识"(STAFF 文字胶囊)和"成就奖章"(圆形)分成两套形状;我们现在把"验证标识"和"成就"都做成六边形,是形状语义重叠,建议分开。
| 设计系统 | 形状 | 层次 | 尺寸 / 数值 | 状态与语义 | 纪律(可直接执行的规则) | 出处 | |
|---|---|---|---|---|---|---|---|
| Material 3 – Badge | 小圆点 / 小圆角胶囊 | 附着在 icon 右上角 | small badge(点)与 large badge(带 1 个字符),规范在 m3 组件页(JS 渲染,需浏览器打开) | "有新内容 / 未读数",不承载身份 | Badge 只用于通知类计数 | M3 Badges guidelines / Android Compose Badge 文档 | |
| Apple HIG | 系统角标 | — | 官方 HIG 目录(badge 属于 status indicator 家族) | 未读 / 状态 | 官方索引 | Apple HIG | |
| Atlassian – Lozenge | 小圆角胶囊(组件名叫 Lozenge,不叫 Badge) | 纯色底 + 深字 | 两档视觉权重 bold / subtle | 语义状态:default / inprogress / moved / new / removed / success(灰 / 蓝 / 黄 / 紫 / 红 / 绿) | 状态色 = 语义,不许随主题乱改 | Atlassian Design: Lozenge(正文 JS 渲染,浏览器打开可见 appearance 列表) | |
| Shopify Polaris – Badge | 圆角胶囊 | 底色 + 文字(可带图标) | 官方给 size 档位 | tone 表达语义、progress 表达"进行中" | 语义靠 tone,不靠自选色 | Polaris Badge(Web Components) / 官方迁移文档 | |
| IBM Carbon – Tag | 圆角胶囊 | 容器 + 文字 + 可选装饰图标(可关闭的额外带 ×) | 三档 small / medium / large;medium 为默认;当周围组件是 32px 高时用 large | 四种变体:read-only / dismissible / selectable / operational(只有可交互变体才有描边) | tag 组之间四周 8px 间距;标题尽量 < 20 字符;禁止把 tag 当链接 | Carbon Tag 规范(实测抓到正文) | |
| Ant Design – Badge | 圆点 / 数字角标 / Ribbon 缎带 | 独立数字(可 showZero)、dot、status 点 + 文案 | 官方 token:dotSize 6、indicatorHeight 20、indicatorHeightSM 14、paddingInline 8、textFontSize 12、statusSize 6、`size: small \ | medium` | status 五档:success / processing / default / error / warning | 状态色固定五档;溢出用 overflowCount(默认 99)显示 99+ | Ant Design Badge(.md 版含官方 token 表) |
| GitHub Primer – Label | 圆角胶囊 | 底色 + 边框 + 文字 | 组件名 Label(原 Label / State);计数用 CounterLabel | 用于 issue / PR 状态 | 组件清单见官方导航 | Primer Label / Primer 组件总览 | |
| GOV.UK – Tag | 圆角矩形(无圆角胶囊) | 纯色底 + 白/深字 | 官方未给像素梯度(组件级 token) | 颜色语义明确:grey 中性 / blue 新 / green 完成 / yellow 等待 / red 紧急 / purple 等 | 官方明文两条铁律:① 不要用颜色单独传达信息(WCAG 2.2 SC 1.4.1)② 不要做成链接或按钮(会被误认为可点) | GOV.UK Design System: Tag(实测抓到正文) |
可抄结论 5:设计系统给的最硬的四条纪律,我们都能直接用:
99+)| 想抄的东西 | 抄谁 | 具体抄哪一点 |
|---|---|---|
| 稀有度分级 | Steam、PlayStation、GitHub | 用工艺(金属/闪/描边复杂度)分级,不用换色相 |
| "未获得"状态处理 | GitHub Achievements | 未获得不上屏(避免灰色墓碑式 UI),只在成就墙里显示为进度 |
| 徽章墙布局 | Duolingo、GitHub | 网格 + 2 行 × 5 列的密度;个人记录单独一组 |
| 认证类标识 | OpenSea、Magic Eden | 单色 + 无底色 + 无描边,形状与"成就"明确区分 |
| 尺寸纪律 | Carbon | 只留 3 档(我们建议 5 档是为了 hero 场景,见 D.2,但 sm/md 必须是主用档) |
| 交互形状语义 | Carbon | 锁定的徽章不给描边,只有可交互/已获得的才给描边和动效 |
| 无障碍 | GOV.UK | 颜色不能是唯一信号 → 我们补"角标数字 + tooltip + 图标"三重编码 |
---
字段说明:视觉强度 = 在暗底 #0E0E10 上的醒目程度;撞脸风险 = 被认成某个特定产品招牌动效的概率。
conic-gradient(from var(--angle), transparent 0 280deg, color 320deg, transparent 360deg) + @property --angle { syntax:"<angle>" } 让角度可动画;容器 inset:-30%,外层用 evenodd 双路径 mask 切成 1px 边环;关键帧 to { rotate: -1turn }。BorderBeam(官方描述:"An animated beam of light which travels along the border of its container",默认 duration 6s、size 50)、Magic UI ShineBorder;Aceternity 的 Moving Border / Hover Border Gradient / Glowing Effect;pools.trade 徽章。<svg viewBox="0 0 34 38">,<path pathLength="100" fill="none" stroke-width="1.25" stroke-dasharray="100" stroke-dashoffset="100">,hover 时 stroke-dashoffset: 0 + transition: .48s cubic-bezier(.22,.61,.36,1)。用 pathLength 归一化,任何尺寸都不用改数值;transform: rotate(180deg) 可把起点挪到底部顶点(尖顶六边形 180° 对称,形状不变)。onpointermove 写 --mx/--my(CSS 变量),background: radial-gradient(180px circle at var(--mx) var(--my), rgba(255,255,255,.14), transparent 60%),外层 overflow:hidden。不写 JS 的降级:hover 时把光斑固定在中心。Card Spotlight、Spotlight;Vercel / Linear 系的卡片 hover。@keyframes breathe { 0%,100%{ box-shadow: 0 0 0 0 transparent } 50%{ box-shadow: 0 0 10px 1px color-mix(in srgb, var(--c) 30%, transparent) } },2.8s ease-in-out infinite;小尺寸用 filter: drop-shadow() 更贴合 clip-path 形状。Pulsating Button;状态点/在线指示灯(Ant Design status 点);我们现在的 .hbglow 与 .vbadge.rev。background: linear-gradient(105deg, transparent 40%, rgba(255,255,255,.35) 50%, transparent 60%),transform: translateX(-120%) → translateX(120%),0.6–0.9s ease-out,overflow:hidden;用 mask 或 clip-path 继承徽章形状,避免高光溢出六边形。Shimmer Button、Animated Shiny Text;几乎所有 SaaS 的"高级感按钮"。::after { inset:-2px; border:1.5px solid var(--c); border-radius:inherit } + @keyframes burst { from{ transform:scale(.82); opacity:.55 } to{ transform:scale(1.9); opacity:0 } },900ms ×1(不是循环)。Pulsating Button;我们现有 .logo-badge.v::after(badgeRing 2.8s 循环)。transition: transform 160ms cubic-bezier(.34,1.56,.64,1);transform: translateY(-1px) scale(1.03);配合 filter: drop-shadow(0 2px 6px rgba(0,0,0,.5))。磁性版:JS 用鼠标相对位移乘 0.15 写 --tx/--ty。Magnetic Button;我们现有 .hexwrap:hover(已有一半)。filter: saturate(1) brightness(1) → filter: saturate(1.35) brightness(1.12);激进版 hue-rotate(12deg)。对语义色是危险的:hue-rotate 会把 mint 变成别的语义色,破坏我们的五色纪律。Chromatic Image。saturate/brightness 的温和版本。canvas-confetti 或在容器内放 6–10 个伪元素/<i>,每个用 CSS 变量给随机角度 --a 与距离,@keyframes burst { to { transform: rotate(var(--a)) translateY(-14px) scale(.2); opacity:0 } },700ms ×1。Confetti / Particles / Meteors;Duolingo 的成就庆祝。::after { background: linear-gradient(180deg, rgba(255,255,255,.16), transparent 38%); mix-blend-mode: screen; } 叠在形状内;再加 box-shadow: inset 0 1px 0 rgba(255,255,255,.14);底色用"上亮下暗"的两段渐变(见 D.3 的 --hb-fill-top/bottom 具体十六进制值)。Glare Card。stroke-dasharray="20 80" 配合 stroke-dashoffset 做分段;或用静止的 conic-gradient 分段(transparent 0 72deg, var(--c) 72deg 144deg, …)不旋转。pathLength="100" + stroke-dasharray="19 1" 可以做 5 段。Animated Circular Progress Bar;Apple Fitness 的圆环(活动圆环三色闭合)。transition: transform 140ms var(--ease), filter 140ms;transform: scale(1.04);filter: brightness(1.15)。缓动用设计系统 token,别自己编。motionDurationMid、motionDurationSlow、motionEaseOutBack)。| 排序 | 手法 | 视觉强度 | 撞脸风险 | 20–40px 可用? | 建议 |
|---|---|---|---|---|---|
| 1 | B1 conic 旋转边框 | 强 | 中 | 勉强(彩色会糊) | 徽章上停用,留给 CTA 按钮 |
| 2 | B2 描边逐段点亮 | 中 | 低 | ✅ 最佳 | 主推(hover) |
| 3 | B4 发光呼吸 | 弱—中 | 低 | ✅ | 保留(只给验证类) |
| 4 | B10 拟态金属高光 | 弱—中 | 低 | ✅ | 必加(提升质感) |
| 5 | B6 一次性 ring burst | 中 | 低 | ✅ | 主推(新达成) |
| 6 | B5 扫光条 shine | 中 | 低—中 | ✅(一次性) | 备选 |
| 7 | B11 分段进度 | 中 | 低 | ✅ | 备选(表达进度) |
| 8 | B7 磁性抬升 | 弱 | 低 | ✅ | 保留现有的一半 |
| 9 | B12 缩放 + 描边亮度 | 弱 | 低 | ✅ | 保底 |
| 10 | B9 粒子 burst | 强 | 低 | 只适合 hero | 只给 hero / 解锁弹窗 |
| 11 | B3 径向 spotlight | 中 | 低 | ❌ | 只给 ≥96px |
| 12 | B8 hue-rotate | 中 | 低 | ✅ | 不推荐(会破坏五色语义) |
---
是行业通用手法,单独用不构成抄袭。
四条证据:
@property --a 角度变量 + CSS Mask + conic 做发光边框,并附两个 CodePen)。css-tip.com/glowing-borderBorderBeam(官方描述:"An animated beam of light which travels along the border of its container"),另有 ShineBorder。Magic UI Border BeamMoving Border、Hover Border Gradient、Glowing Effect、Tracing Beam 都是同一族。Aceternity 组件库上面证明的是「用手法」不构成抄袭。它不能证明我们现在的实现没问题。逐项对比我们和 pools.trade 的线上 CSS:
| 对比项 | pools.trade | 我们 | 是否撞 |
|---|---|---|---|
| 渐变色窗 | transparent 0→280deg,光 320deg,transparent 360deg | 同上,逐字相同 | ❌ 撞 |
| 时长 / 缓动 | .3s linear | .3s linear(hover)/ 1.6s linear infinite(钉住) | ❌ 撞 |
| 关键帧 | rotate -1turn | rotate -1turn | ❌ 撞 |
| 图层容器 | inset:-30% | inset:-30% | ❌ 撞 |
| 切边方式 | evenodd 双路径 mask 切细边环 | evenodd 双路径 mask 切细边环(厚度 2.6px vs 1px) | ❌ 撞 |
| 交互语义 | hover 亮一圈 | hover 亮一圈 | ❌ 撞 |
| 形状 | 平顶圆角六边 36×36 | 尖顶六边 34×38 | ✅ 不撞 |
| 配色 | 单色 --pools-badge-base | 五色语义 | ✅ 不撞 |
| 光晕 | 径向 glow 4s 呼吸 | 径向 glow 4s 呼吸(hbBreathe 4s) | ❌ 撞 |
结论:C.1 说的是"手法公共",C.2 说的是"参数私有"。我们踩的是 C.2:在公共手法上复刻了别人的具体参数,还在同一个赛道(暗色加密产品)里。这种情况业内一般不会走法律程序,但会在 Twitter/社区被做"对比图"——这才是老板真正怕的。
处置原则(建议直接写进规范):
推荐 ①(主):B2 描边逐段点亮(SVG stroke-dashoffset)
pathLength="100" 归一化后,24px 和 112px 用同一套数值;stroke 1px 在 24px 上依然可辨(conic 的 1px 边环在 24px 上几乎看不见)。推荐 ②(配备):B10 拟态金属高光 + B6 一次性 ring burst
linear-gradient + mix-blend-mode。推荐 ③(备选):B11 分段环形进度(静止 conic 分段 / dasharray)
同时建议:把 conic 旋转边框保留但移位——只用在主 CTA 按钮(Launch / Buy)和 hero 区,那里是整个行业的公共位置,不构成产品识别;徽章上撤掉。
---
结论:不要换成盾形/超椭圆,保留尖顶六边形,只把尖角削圆。
理由:
形状参数:圆角半径建议 r ≈ 12% 宽度(34px → r=4;24px → r=3)。对比 pools.trade 是 r ≈ 16.7% 宽度的平顶圆角六边形——方向不同、比例不同。
下面所有 path() 都按各自 viewBox 光栅化自检过(闭合正确、无交叉、比例符合 h = 1.1547w),可直接粘贴。
可直接粘贴的 clip-path: path()(尖顶、圆角、h = 1.1547w):
```css
/ 34 × 38 (md,默认) r=4 /
clip-path: path("M 13.508 1.951 Q 17 0 20.492 1.951 L 30.508 7.549 Q 34 9.5 34 13.5 L 34 24.5 Q 34 28.5 30.508 30.451 L 20.492 36.049 Q 17 38 13.508 36.049 L 3.492 30.451 Q 0 28.5 0 24.5 L 0 13.5 Q 0 9.5 3.492 7.549 Z");
/ 24 × 27 (sm,列表行) r=3 /
clip-path: path("M 9.385 1.471 Q 12 0 14.615 1.471 L 21.385 5.279 Q 24 6.75 24 9.75 L 24 17.25 Q 24 20.25 21.385 21.721 L 14.615 25.529 Q 12 27 9.385 25.529 L 2.615 21.721 Q 0 20.25 0 17.25 L 0 9.75 Q 0 6.75 2.615 5.279 Z");
/ 48 × 55 (lg,详情页头部) r=6 /
clip-path: path("M 18.794 2.983 Q 24 0 29.206 2.983 L 42.794 10.767 Q 48 13.75 48 19.75 L 48 35.25 Q 48 41.25 42.794 44.233 L 29.206 52.017 Q 24 55 18.794 52.017 L 5.206 44.233 Q 0 41.25 0 35.25 L 0 19.75 Q 0 13.75 5.206 10.767 Z");
/ 96 × 111 (hero,成就墙/解锁弹窗) r=12 /
clip-path: path("M 37.611 6.006 Q 48 0 58.389 6.006 L 85.611 21.744 Q 96 27.75 96 39.75 L 96 71.25 Q 96 83.25 85.611 89.256 L 58.389 104.994 Q 48 111 37.611 104.994 L 10.389 89.256 Q 0 83.25 0 71.25 L 0 39.75 Q 0 27.75 10.389 21.744 Z");
```
(备选)传奇档专用盾形(只给"传奇"这一档用一次,作为形状级稀有度信号):
```css
/ 盾形 34 × 38 r=3.5 /
clip-path: path("M 3.264 3.039 Q 5 0 8.5 0 L 25.5 0 Q 29 0 30.736 3.039 L 31.264 3.961 Q 33 7 32.314 10.432 L 30.686 18.568 Q 30 22 27.793 24.716 L 19.207 35.284 Q 17 38 14.793 35.284 L 6.207 24.716 Q 4 22 3.314 18.568 L 1.686 10.432 Q 1 7 2.736 3.961 Z");
```
(备选)超椭圆/方圆(如果最终决定放弃六边形):
```css
/ 超椭圆 34 × 38,n=4,圆角化 /
clip-path: path("M 33.964 17.801 Q 34 19 33.964 20.199 L 33.744 27.467 Q 33.708 28.666 33.433 29.834 L 33.095 31.267 Q 32.82 32.435 32.203 33.464 L 31.913 33.948 Q 31.295 34.977 30.335 35.697 L 29.981 35.962 Q 29.021 36.681 27.87 37.02 L 26.8 37.335 Q 25.649 37.673 24.449 37.719 L 18.199 37.955 Q 17 38 15.801 37.955 L 9.551 37.719 Q 8.351 37.673 7.2 37.335 L 6.13 37.02 Q 4.979 36.681 4.019 35.962 L 3.665 35.697 Q 2.705 34.977 2.087 33.948 L 1.797 33.464 Q 1.18 32.435 0.905 31.267 L 0.567 29.834 Q 0.292 28.666 0.256 27.467 L 0.036 20.199 Q 0 19 0.036 17.801 L 0.256 10.533 Q 0.292 9.334 0.567 8.166 L 0.905 6.733 Q 1.18 5.565 1.797 4.536 L 2.087 4.052 Q 2.705 3.023 3.665 2.303 L 4.019 2.038 Q 4.979 1.319 6.13 0.98 L 7.2 0.665 Q 8.351 0.327 9.551 0.281 L 15.801 0.045 Q 17 0 18.199 0.045 L 24.449 0.281 Q 25.649 0.327 26.8 0.665 L 27.87 0.98 Q 29.021 1.319 29.981 2.038 L 30.335 2.303 Q 31.295 3.023 31.913 4.052 L 32.203 4.536 Q 32.82 5.565 33.095 6.733 L 33.433 8.166 Q 33.708 9.334 33.744 10.533 Z");
```
| token | 尺寸 (w×h) | 圆角 r | 图标 | 数字字号 | 描边 stroke | 光晕 drop-shadow | 用在哪 | 频率 |
|---|---|---|---|---|---|---|---|---|
--bdg-xs | 16 × 18 | 2 | 10px | 8px | 1px | 0 0 4px / 30% | 行内文字后、"×3"这种极小角标 | 少 |
--bdg-sm | 24 × 27 | 3 | 11px | 9px | 1px | 0 0 5px / 35% | 列表行 / 卡片行(主用) | 高 |
--bdg-md | 34 × 38 | 4 | 16px | 11px | 1.25px | 0 0 6px / 45% | 详情页 / 主展示(主用) | 高 |
--bdg-lg | 48 × 55 | 6 | 22px | 15px | 1.5px | 0 0 8px / 45% | 代币详情页头部 | 中 |
--bdg-hero | 96 × 111 | 12 | 44px | 28px | 2px | 0 0 16px / 50% | 成就墙 / 解锁弹窗 | 低 |
纪律(来自 Carbon 的三档原则,我们扩展到五档但主用只有两档):
path() 后建议一并对齐,直接用 D.1 的数值。层级自下而上(对应我们现有的类名,方便直接改):
| # | 部件(类名) | 作用 | 具体参数 |
|---|---|---|---|
| 1 | .hbglow | 外发光光环 | background: radial-gradient(circle, var(--hb-glow), transparent 70%);inset: -4px(sm 用 -3px,hero 用 -12px)。注意:.hbglow 是环形光晕,会溢出六边形——这是有意的(pools 也有),保留 |
| 2 | .hbhex | 形状 | clip-path: path(D.1 的路径);background: var(--surface-2) |
| 3 | .hbfill | 底色(上亮下暗 + 顶部径向提亮) | 见下方代码;这是"从塑料到金属"的关键 |
| 4 | .hb-spec(新增) | 顶部拟态高光 | background: linear-gradient(180deg, rgba(255,255,255,.16), transparent 38%);mix-blend-mode: screen;必须也在 clip-path 内 |
| 5 | .hb-rim-svg(替换 .hbrim) | 描边(可动画) | SVG <path> 同一路径,stroke-width 按 D.2 表;颜色 = linearGradient 从 var(--hb) 100% → 35% 透明 |
| 6 | .hbico | 图标 | lucide,stroke-width: 1.75,尺寸按 D.2;颜色 var(--hb-ico) |
| 7 | .hbnum | 数字/文字 | font-family: var(--font-mono);font-variant-numeric: tabular-nums;字号按 D.2;颜色 var(--hb-ico) |
底色与描边颜色 token(已按我们的 #0E0E10 底与五色算好十六进制,可直接用):
```css
/ 底色:上 = 语义色 20% + 背景 80%;下 = 语义色 7% + 背景 93% /
.hbslot.mint { --hb:#7FFFAD; --hb-fill-top:#253E2F; --hb-fill-bot:#161F1B; --hb-ico:#89FFB4; --hb-rim-2:#3B6E4F; --hb-glow:rgba(127,255,173,.42); }
.hbslot.pink { --hb:#FF6B9E; --hb-fill-top:#3E212C; --hb-fill-bot:#1F151A; --hb-ico:#FF77A6; --hb-rim-2:#6E3349; --hb-glow:rgba(255,107,158,.42); }
.hbslot.gold { --hb:#FFC84D; --hb-fill-top:#3E331C; --hb-fill-bot:#1F1B14; --hb-ico:#FFCC5B; --hb-rim-2:#6E5828; --hb-glow:rgba(255,200,77,.42); }
.hbslot.violet { --hb:#A855F7; --hb-fill-top:#2D1C3E; --hb-fill-bot:#191320; --hb-ico:#AF63F8; --hb-rim-2:#4C2A6C; --hb-glow:rgba(168,85,247,.45); }
.hbslot.cyan { --hb:#22D3EE; --hb-fill-top:#12353C; --hb-fill-bot:#0F1C20; --hb-ico:#34D7EF; --hb-rim-2:#165D69; --hb-glow:rgba(34,211,238,.42); }
.hbfill {
position: absolute; inset: 0;
clip-path: path(/ 同 .hbhex 的路径 /);
background:
radial-gradient(120% 120% at 50% 0%, color-mix(in srgb, var(--hb) 26%, transparent), transparent 70%),
linear-gradient(180deg, var(--hb-fill-top), var(--hb-fill-bot));
}
```
锁定态(未获得)——重要:不要做"灰色墓碑"。按 GitHub 的做法(未获得的不上屏)+ Carbon 的规则(不可交互的标识不给描边):
```css
.hbslot.locked .hbfill { filter: grayscale(.65) brightness(.62); opacity: .5; }
.hbslot.locked .hb-rim-path { stroke-dasharray: 4 5; stroke-dashoffset: 0; opacity: .28; } / 虚线 = 未完成 /
.hbslot.locked { cursor: default; }
.hbslot.locked .hbglow { display: none; }
```
| 状态 | 触发 | 描边 | 底色 | 光晕 | 位移 |
|---|---|---|---|---|---|
| locked 未获得 | 无数据 | 1px 虚线,rgba(255,255,255,.28) | grayscale(.65) brightness(.62),opacity .5 | 无 | 无 |
| obtained 已获得 | 有数据 | 实线 1.25px,var(--hb) → 35% 透明渐变;opacity .38(静息) | 正常(上亮下暗 + 顶部径向提亮) | drop-shadow(0 0 6px / 45%) | 无 |
| hover | 鼠标/键盘 focus | stroke-dashoffset: 100 → 0,opacity → 1 | 顶部径向提亮从 26% → 34% | 6px → 10px / 60% | translateY(-1px) scale(1.03) |
active / pinned(.on) | 点击 | 满亮实线 | 同 hover | 10px 常亮,不循环动画 | 保持 hover 位移 |
| rare 稀有 | 数据标记 | 描边改为双层:外 1.25px 语义色 + 内 0.75px 白色 12%(<path> 叠两条) | 顶部高光从 38% 拉长到 52% | 8px / 55% | 无 |
| legendary 传奇 | 数据标记 | 描边 + 斜向扫光(B5,一次性 0.9s);或换盾形(D.1 备选) | 高光 + saturate(1.15) | 10px / 60% | 无 |
| just-earned 新达成 | 状态从 locked→obtained | 描边 480ms 走满一圈(B2) | 同 obtained | 一次性 ring burst 900ms(B6) | scale(.9) → 1.06 → 1 |
稀有度分级原则(抄 Steam/GitHub/PS):色相只表语义(mint=验证/pink=社群/gold=里程碑/violet=拍卖/cyan=数据),稀有度用"工艺"表达:单描边 → 双层描边 → 双层描边 + 扫光/盾形。这样五色不用扩成十色,也不会出现"紫色比青色更高级"这种无意义暗示。
为什么选它(一句话版本,可直接跟老板说):conic 是"绕圈",改成"描边自下而上闭合"后,① 24px 下也看得清;② 是"补齐/完成"的语义,而不是装饰性扫光;③ 参数和 pools.trade 没有一项相同。
HTML 结构(新增 .hb-rim-svg,删掉 .hbrim):
```html
<span class="hbslot mint" style="--i:0">
<span class="hbglow"></span>
<span class="hbhex">
<span class="hbfill"></span>
<span class="hb-spec"></span>
<span class="hbico"><!-- lucide svg 16px --></span>
<svg class="hb-rim-svg" viewBox="0 0 34 38" aria-hidden="true">
<defs>
<linearGradient id="rim-mint" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#7FFFAD"/>
<stop offset="1" stop-color="#7FFFAD" stop-opacity=".35"/>
</linearGradient>
</defs>
<path class="hb-rim-path" pathLength="100" stroke="url(#rim-mint)"
d="M 13.508 1.951 Q 17 0 20.492 1.951 L 30.508 7.549 Q 34 9.5 34 13.5 L 34 24.5 Q 34 28.5 30.508 30.451 L 20.492 36.049 Q 17 38 13.508 36.049 L 3.492 30.451 Q 0 28.5 0 24.5 L 0 13.5 Q 0 9.5 3.492 7.549 Z"/>
</svg>
</span>
</span>
```
CSS:
```css
/ 描边层:rotate(180deg) 把路径起点挪到底部顶点(尖顶六边形 180° 对称,形状不变) /
.hb-rim-svg {
position: absolute; inset: 0; width: 100%; height: 100%;
z-index: 3; pointer-events: none; overflow: visible;
transform: rotate(180deg);
}
.hb-rim-path {
fill: none;
stroke-width: 1.25; / sm=1 lg=1.5 hero=2 /
stroke-linecap: round;
stroke-linejoin: round;
stroke-dasharray: 100; / pathLength=100,无需算周长 /
stroke-dashoffset: 100; / 静息:整圈隐藏 /
opacity: .38; / 静息:只保留 38% 亮度的完整细边 /
transition: stroke-dashoffset 480ms cubic-bezier(.22,.61,.36,1),
opacity 220ms ease-out;
}
.hbslot:hover .hb-rim-path,
.hbslot:focus-visible .hb-rim-path,
.hbslot.on .hb-rim-path { stroke-dashoffset: 0; opacity: 1; }
/ 顶部拟态高光 /
.hb-spec {
position: absolute; inset: 0; pointer-events: none; z-index: 2;
clip-path: path(/ 同 .hbhex /);
background: linear-gradient(180deg, rgba(255,255,255,.16), transparent 38%);
mix-blend-mode: screen;
}
/ 抬升 + 光晕 /
.hbslot { transition: transform 160ms cubic-bezier(.34,1.56,.64,1), filter 220ms ease-out; }
.hbslot:hover, .hbslot:focus-visible, .hbslot.on { transform: translateY(-1px) scale(1.03); }
.hbslot:hover .hbhex { filter: drop-shadow(0 0 10px color-mix(in srgb, var(--hb) 60%, transparent)); }
/ 新达成:一次性 ring burst(900ms ×1,绝不循环) /
@keyframes hbRingBurst {
from { transform: scale(.82); opacity: .55; }
to { transform: scale(1.9); opacity: 0; }
}
.hbslot.just-earned::after {
content: ""; position: absolute; inset: -2px; border-radius: 999px;
border: 1.5px solid var(--hb); pointer-events: none;
animation: hbRingBurst 900ms cubic-bezier(.16,1,.3,1) 1 forwards;
}
/ 无障碍:减弱动态效果时全关(MDN 官方建议) /
@media (prefers-reduced-motion: reduce) {
.hb-rim-path { transition: none; stroke-dashoffset: 0; opacity: .7; }
.hbslot, .hbglow, .hb-spec, .hbslot.just-earned::after { transition: none !important; animation: none !important; transform: none; }
}
```
时长 / 缓动总表(改代码照着填):
| 动作 | 时长 | 缓动 | 触发 | 备注 |
|---|---|---|---|---|
| 内描边闭合 | 480ms | cubic-bezier(.22,.61,.36,1) | hover / focus / .on | dashoffset 100→0,从底部顶点向两侧合拢 |
| 离开复位 | 480ms | 同上(自动反向) | mouseleave | 反向"褪回",视觉上像"收回" |
| 描边亮度 | 220ms | ease-out | hover | opacity .38→1 |
| 抬升 | 160ms | cubic-bezier(.34,1.56,.64,1) | hover | translateY(-1px) scale(1.03) |
| 外发光 | 220ms | ease-out | hover | drop-shadow 0 0 6px → 10px |
| 入场错峰 | 400ms + 55ms×i | cubic-bezier(.34,1.56,.64,1) | 首次渲染 | 保留现有 hbEnter + stagger |
| 新达成 burst | 900ms ×1 | cubic-bezier(.16,1,.3,1) | locked→obtained | 只播一次 |
| 验证类呼吸 | 2800ms 循环 | ease-in-out | 仅 .vbadge.rev / 验证标识 | 与我们的 2.8s 节拍一致,成就徽章不呼吸 |
钉住 .on | 不循环 | — | 点击 | 静态满亮;取消现在的 1.6s conic 无限转 |
⚠️ 不要做的三件事:① 不要在 24px 徽章上跑彩色 conic(五色会糊成彩色噪点);② 不要给成就徽章加循环呼吸(只有"认证"类才需要"活着"的信号);③ 不要把 burst 做成循环(会从"达成时刻"退化成装饰)。
改一个文件就够:演示站-en/assets/styles.css(以及 软件开发与工程设计/演示站-线上版/assets/styles.css 同步)
| # | 改动 | 具体位置 |
|---|---|---|
| 1 | .hbhex / .hexbadge 的 clip-path: polygon(...) 全部换成 D.1 的 path()(34/24 两档) | .hbhex、.hbfill、.hexbadge、.hbrim 的 mask SVG |
| 2 | 新增 .hb-spec 高光层,并在 JS/HTML 里插入该节点 | app.js 里生成 .hbhex 的模板处 |
| 3 | 删除 .hbrim(conic + mask)与 @keyframes hbRimShine;替换为 .hb-rim-svg + .hb-rim-path | CSS 第 762–880 行区块 |
| 4 | .hbslot 五色变量补齐 --hb-fill-top/--hb-fill-bot/--hb-ico/--hb-rim-2(值见 D.3) | .hbslot.mint/.pink/.gold/.violet/.cyan |
| 5 | 新增 .locked / .rare / .legendary / .just-earned 四个状态类 | 同上区块 |
| 6 | .hbglow 呼吸从 4s 改 2.8s(与设计规范 badgeBreath 对齐),并且只给验证类;成就徽章的 glow 改为静态 | .hbglow |
| 7 | conic 保留为 CTA 专用:把现有 conic 规则移到 .btn-launch(或 .pools-cta)下 | 新建 class,不动按钮语义 |
| 8 | .sm 档同步路径与 stroke 宽度(24×27,r=3,stroke 1) | .hbslot.sm |
验收清单(改完自己过一遍):
conic-gradient:徽章区块里应该搜不到---
产品 / 平台
设计系统
动效 / 技术
conic-gradient():<https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/gradient/conic-gradient>stroke-dashoffset:<https://developer.mozilla.org/zh-CN/docs/Web/SVG/Reference/Attribute/stroke-dashoffset>prefers-reduced-motion:<https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/prefers-reduced-motion>本地参照(未修改)
演示站-en/assets/styles.css(我们现有 .hexbadge / .hbslot 实现)演示站-en/pools-spec.html(pools.trade 设计规范)pools-clone-deploy/assets/root-D9nZBKc8.css(pools.trade 线上 CSS,.pools-badge-*)