design.json 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. {
  2. "schemaVersion": 2,
  3. "generatedAt": "2026-05-13T00:00:00.000Z",
  4. "title": "Design System: haha-admin-mp",
  5. "extensions": {
  6. "colorMeta": {
  7. "amber-primary": {
  8. "role": "primary",
  9. "displayName": "Amber Primary",
  10. "canonical": "oklch(78% 0.17 85)",
  11. "tonalRamp": [
  12. "oklch(20% 0.04 85)",
  13. "oklch(35% 0.08 85)",
  14. "oklch(48% 0.12 85)",
  15. "oklch(60% 0.15 85)",
  16. "oklch(70% 0.17 85)",
  17. "oklch(78% 0.17 85)",
  18. "oklch(88% 0.12 85)",
  19. "oklch(95% 0.04 85)"
  20. ]
  21. },
  22. "amber-bg": {
  23. "role": "primary-bg",
  24. "displayName": "Amber Background",
  25. "canonical": "oklch(97% 0.02 85)",
  26. "tonalRamp": [
  27. "oklch(98% 0.01 85)",
  28. "oklch(97% 0.02 85)",
  29. "oklch(96% 0.025 85)",
  30. "oklch(95% 0.03 85)",
  31. "oklch(94% 0.035 85)",
  32. "oklch(92% 0.05 85)",
  33. "oklch(90% 0.07 85)",
  34. "oklch(85% 0.1 85)"
  35. ]
  36. },
  37. "orange-accent": {
  38. "role": "secondary",
  39. "displayName": "Orange Accent",
  40. "canonical": "oklch(62% 0.2 50)",
  41. "tonalRamp": [
  42. "oklch(18% 0.05 50)",
  43. "oklch(30% 0.08 50)",
  44. "oklch(42% 0.12 50)",
  45. "oklch(52% 0.16 50)",
  46. "oklch(62% 0.2 50)",
  47. "oklch(72% 0.18 50)",
  48. "oklch(84% 0.1 50)",
  49. "oklch(94% 0.03 50)"
  50. ]
  51. },
  52. "green-success": {
  53. "role": "semantic",
  54. "displayName": "Green Success",
  55. "canonical": "oklch(62% 0.17 160)",
  56. "tonalRamp": [
  57. "oklch(18% 0.05 160)",
  58. "oklch(32% 0.08 160)",
  59. "oklch(45% 0.12 160)",
  60. "oklch(55% 0.15 160)",
  61. "oklch(62% 0.17 160)",
  62. "oklch(72% 0.15 160)",
  63. "oklch(84% 0.08 160)",
  64. "oklch(94% 0.03 160)"
  65. ]
  66. },
  67. "red-error": {
  68. "role": "semantic",
  69. "displayName": "Red Error",
  70. "canonical": "oklch(55% 0.21 25)",
  71. "tonalRamp": [
  72. "oklch(18% 0.06 25)",
  73. "oklch(28% 0.1 25)",
  74. "oklch(40% 0.15 25)",
  75. "oklch(50% 0.18 25)",
  76. "oklch(55% 0.21 25)",
  77. "oklch(65% 0.18 25)",
  78. "oklch(78% 0.1 25)",
  79. "oklch(93% 0.03 25)"
  80. ]
  81. },
  82. "amber-warning": {
  83. "role": "semantic",
  84. "displayName": "Amber Warning",
  85. "canonical": "oklch(68% 0.16 75)",
  86. "tonalRamp": [
  87. "oklch(18% 0.04 75)",
  88. "oklch(30% 0.07 75)",
  89. "oklch(44% 0.1 75)",
  90. "oklch(56% 0.13 75)",
  91. "oklch(68% 0.16 75)",
  92. "oklch(78% 0.14 75)",
  93. "oklch(86% 0.08 75)",
  94. "oklch(95% 0.03 75)"
  95. ]
  96. },
  97. "slate-text-primary": {
  98. "role": "neutral-text",
  99. "displayName": "Slate Text Primary",
  100. "canonical": "oklch(25% 0.01 260)",
  101. "tonalRamp": [
  102. "oklch(15% 0.01 260)",
  103. "oklch(20% 0.01 260)",
  104. "oklch(25% 0.01 260)",
  105. "oklch(35% 0.01 260)",
  106. "oklch(45% 0.01 260)",
  107. "oklch(60% 0.01 260)",
  108. "oklch(80% 0.005 85)",
  109. "oklch(94% 0.005 85)"
  110. ]
  111. },
  112. "ash-page-bg": {
  113. "role": "neutral-bg",
  114. "displayName": "Ash Page Background",
  115. "canonical": "oklch(97% 0.005 85)",
  116. "tonalRamp": [
  117. "oklch(99% 0.002 85)",
  118. "oklch(97% 0.005 85)",
  119. "oklch(95% 0.006 85)",
  120. "oklch(92% 0.007 85)",
  121. "oklch(88% 0.008 85)",
  122. "oklch(82% 0.008 85)",
  123. "oklch(72% 0.007 85)",
  124. "oklch(58% 0.006 85)"
  125. ]
  126. },
  127. "white-card-bg": {
  128. "role": "neutral-surface",
  129. "displayName": "White Card Background",
  130. "canonical": "oklch(100% 0.002 85)",
  131. "tonalRamp": [
  132. "oklch(100% 0 0)",
  133. "oklch(100% 0.002 85)",
  134. "oklch(98% 0.003 85)",
  135. "oklch(96% 0.004 85)",
  136. "oklch(93% 0.005 85)",
  137. "oklch(87% 0.006 85)",
  138. "oklch(76% 0.007 85)",
  139. "oklch(62% 0.006 85)"
  140. ]
  141. },
  142. "ash-border": {
  143. "role": "neutral-border",
  144. "displayName": "Ash Border",
  145. "canonical": "oklch(90% 0.005 260)",
  146. "tonalRamp": [
  147. "oklch(96% 0.003 260)",
  148. "oklch(93% 0.004 260)",
  149. "oklch(90% 0.005 260)",
  150. "oklch(85% 0.005 260)",
  151. "oklch(78% 0.005 260)",
  152. "oklch(68% 0.004 260)",
  153. "oklch(52% 0.003 260)",
  154. "oklch(32% 0.002 260)"
  155. ]
  156. }
  157. },
  158. "typographyMeta": {
  159. "display": { "displayName": "Display", "purpose": "订单金额、统计大数。仅在关键数据上出现。" },
  160. "headline": { "displayName": "Headline", "purpose": "页面标题、卡片标题、弹窗标题。" },
  161. "title": { "displayName": "Title", "purpose": "主要正文、列表项名称、标签。最广泛的字号。" },
  162. "body": { "displayName": "Body", "purpose": "正文信息、表单输入、描述文字。28rpx + 1.6 line-height。" },
  163. "label": { "displayName": "Label", "purpose": "标签、徽章、meta 文字。22rpx + 0.02em letter-spacing。" }
  164. },
  165. "shadows": [
  166. { "name": "card-rest", "value": "0 2rpx 12rpx rgba(0,0,0,0.05)", "purpose": "所有卡片和可交互表面在静止态的标准阴影。" },
  167. { "name": "card-subtle", "value": "0 2rpx 8rpx rgba(0,0,0,0.04)", "purpose": "轻量阴影,用于列表卡片之间的细微区分。" },
  168. { "name": "bottom-bar", "value": "0 -2rpx 12rpx rgba(0,0,0,0.05)", "purpose": "固定底部栏的方向性阴影,指向上方。" },
  169. { "name": "primary-glow", "value": "0 6rpx 20rpx rgba(255,193,7,0.4)", "purpose": "唯一彩色阴影。仅用于扫码FAB,暖金散射强调首要地位。" }
  170. ],
  171. "motion": [
  172. { "name": "ease-press", "value": "opacity 0.15s ease", "purpose": "所有按钮和可点击元素的 active 态反馈。通过 opacity 变化而非 layout property 动画。" },
  173. { "name": "ease-pulse", "value": "1.2s ease-in-out infinite", "purpose": "加载 pulse dots 的序列动画。不适用 ease-out-quart 因其为循环动画。" },
  174. { "name": "ease-spin", "value": "1s linear infinite", "purpose": "加载 spinner 的旋转动画。" }
  175. ],
  176. "breakpoints": [
  177. { "name": "mobile", "value": "375px-414px", "purpose": "微信小程序标准视口宽度。" }
  178. ]
  179. },
  180. "components": [
  181. {
  182. "name": "Primary Button",
  183. "kind": "button",
  184. "refersTo": "button-primary",
  185. "description": "页面级主操作:保存、退款、确认。暖金填充胶囊。",
  186. "html": "<view class=\"ds-btn-primary\"><text class=\"ds-btn-primary-text\">保存</text></view>",
  187. "css": ".ds-btn-primary { background: #FFC107; border-radius: 48rpx; padding: 28rpx 0; display: flex; align-items: center; justify-content: center; transition: opacity 0.15s ease; cursor: pointer; } .ds-btn-primary:active { opacity: 0.8; } .ds-btn-primary-text { font-size: 32rpx; font-weight: 600; color: #1e293b; }"
  188. },
  189. {
  190. "name": "Secondary Action Button",
  191. "kind": "button",
  192. "refersTo": "button-secondary",
  193. "description": "卡片内次级操作:查看详情、筛选、复制。填充底色无边框。",
  194. "html": "<view class=\"ds-btn-secondary\"><text class=\"ds-btn-secondary-text\">查看详情</text></view>",
  195. "css": ".ds-btn-secondary { background: #f1f5f9; border-radius: 8rpx; padding: 8rpx 24rpx; display: inline-flex; align-items: center; justify-content: center; transition: opacity 0.15s ease; } .ds-btn-secondary:active { opacity: 0.7; } .ds-btn-secondary-text { font-size: 24rpx; color: #475569; font-weight: 500; }"
  196. },
  197. {
  198. "name": "Surface Card",
  199. "kind": "card",
  200. "refersTo": "card-surface",
  201. "description": "信息容器。白色背景,微阴影,中等圆角。用于列表项和内容区。",
  202. "html": "<view class=\"ds-card\"><text class=\"ds-card-heading\">标题</text><text class=\"ds-card-body\">内容文本行,展示关键信息。</text></view>",
  203. "css": ".ds-card { background: #ffffff; border-radius: 16rpx; padding: 24rpx 32rpx; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.05); margin-bottom: 16rpx; } .ds-card:active { opacity: 0.7; } .ds-card-heading { display: block; font-size: 30rpx; font-weight: 600; color: #1e293b; margin-bottom: 8rpx; } .ds-card-body { display: block; font-size: 28rpx; color: #475569; line-height: 1.6; }"
  204. },
  205. {
  206. "name": "Status Tag - Success",
  207. "kind": "chip",
  208. "refersTo": "status-tag-success",
  209. "description": "成功/正常/完成状态标签。绿底绿字。",
  210. "html": "<view class=\"ds-tag ds-tag-success\"><text>已完成</text></view>",
  211. "css": ".ds-tag { padding: 4rpx 16rpx; border-radius: 8rpx; font-size: 22rpx; font-weight: 500; display: inline-flex; align-items: center; justify-content: center; } .ds-tag-success { background: #ecfdf5; color: #10b981; }"
  212. },
  213. {
  214. "name": "Status Tag - Warning",
  215. "kind": "chip",
  216. "refersTo": "status-tag-warning",
  217. "description": "待处理/未支付状态标签。琥珀底琥珀字。",
  218. "html": "<view class=\"ds-tag ds-tag-warning\"><text>待支付</text></view>",
  219. "css": ".ds-tag { padding: 4rpx 16rpx; border-radius: 8rpx; font-size: 22rpx; font-weight: 500; display: inline-flex; align-items: center; justify-content: center; } .ds-tag-warning { background: #fffbeb; color: #f59e0b; }"
  220. },
  221. {
  222. "name": "Status Tag - Error",
  223. "kind": "chip",
  224. "refersTo": "status-tag-error",
  225. "description": "失败/退款/故障状态标签。红底红字。",
  226. "html": "<view class=\"ds-tag ds-tag-error\"><text>已退款</text></view>",
  227. "css": ".ds-tag { padding: 4rpx 16rpx; border-radius: 8rpx; font-size: 22rpx; font-weight: 500; display: inline-flex; align-items: center; justify-content: center; } .ds-tag-error { background: #fef2f2; color: #ef4444; }"
  228. },
  229. {
  230. "name": "Navigation Bar",
  231. "kind": "nav",
  232. "refersTo": null,
  233. "description": "固定顶部导航栏。居中标题,左侧返回箭头,支持安全区域。",
  234. "html": "<view class=\"ds-navbar\"><view class=\"ds-navback\"><view class=\"ds-navback-arrow\"></view></view><text class=\"ds-navtitle\">页面标题</text></view>",
  235. "css": ".ds-navbar { position: fixed; top: 0; left: 0; right: 0; z-index: 999; background: #ffffff; padding-top: env(safe-area-inset-top); } .ds-navback { width: 64rpx; height: 64rpx; display: flex; align-items: center; justify-content: center; border-radius: 50%; transition: background 0.15s; } .ds-navback:active { background: rgba(0,0,0,0.05); } .ds-navback-arrow { width: 20rpx; height: 20rpx; border-left: 4rpx solid #1e293b; border-bottom: 4rpx solid #1e293b; transform: rotate(45deg); margin-left: 8rpx; } .ds-navtitle { font-size: 34rpx; font-weight: 600; color: #1e293b; }"
  236. },
  237. {
  238. "name": "Tab Bar",
  239. "kind": "nav",
  240. "refersTo": null,
  241. "description": "固定底部标签栏。4 个标准 Tab 围绕中央扫码 FAB。激活态变暖金。",
  242. "html": "<view class=\"ds-tabbar\"><view class=\"ds-tab ds-tab-active\"><view class=\"ds-tab-icon\"></view><text class=\"ds-tab-label\">工作台</text></view><view class=\"ds-tab\"><view class=\"ds-tab-icon\"></view><text class=\"ds-tab-label\">订单</text></view><view class=\"ds-tabbar-fab\"><view class=\"ds-fab-circle\"></view><text class=\"ds-fab-label\">扫码</text></view><view class=\"ds-tab\"><view class=\"ds-tab-icon\"></view><text class=\"ds-tab-label\">设备</text></view><view class=\"ds-tab\"><view class=\"ds-tab-icon\"></view><text class=\"ds-tab-label\">我的</text></view></view>",
  243. "css": ".ds-tabbar { position: fixed; bottom: 0; left: 0; right: 0; height: 120rpx; background: #ffffff; display: flex; align-items: center; justify-content: space-around; border-top: 1rpx solid #e2e8f0; padding-bottom: env(safe-area-inset-bottom); z-index: 999; box-shadow: 0 -2rpx 12rpx rgba(0,0,0,0.05); } .ds-tab { display: flex; flex-direction: column; align-items: center; justify-content: center; flex: 1; } .ds-tab-label { font-size: 20rpx; color: #1e293b; } .ds-tab-active .ds-tab-label { color: #FFC107; font-weight: 600; } .ds-tabbar-fab { position: relative; width: 120rpx; height: 120rpx; display: flex; flex-direction: column; align-items: center; justify-content: center; } .ds-fab-circle { width: 80rpx; height: 80rpx; background: linear-gradient(135deg, #FFC107, #FFA000); border-radius: 50%; box-shadow: 0 6rpx 20rpx rgba(255,193,7,0.4); transition: transform 0.2s; } .ds-fab-circle:active { transform: scale(0.92); } .ds-fab-label { font-size: 18rpx; color: #1e293b; font-weight: 500; }"
  244. },
  245. {
  246. "name": "Text Input Field",
  247. "kind": "input",
  248. "refersTo": null,
  249. "description": "标准输入框。灰底,圆角,暖金 focus 边框。",
  250. "html": "<input class=\"ds-input\" placeholder=\"请输入姓名\" />",
  251. "css": ".ds-input { background: #f1f5f9; border: 1rpx solid #e2e8f0; border-radius: 12rpx; padding: 24rpx 28rpx; font-size: 28rpx; color: #1e293b; height: 80rpx; width: 100%; box-sizing: border-box; transition: border-color 0.15s; } .ds-input:focus { border-color: #FFC107; } .ds-input::placeholder { color: #cbd5e1; font-size: 24rpx; }"
  252. },
  253. {
  254. "name": "Loading Pulse Dots",
  255. "kind": "custom",
  256. "refersTo": null,
  257. "description": "页面级加载指示器。三个序列脉冲圆点。",
  258. "html": "<view class=\"ds-loading\"><view class=\"ds-pulse-dot\"></view><view class=\"ds-pulse-dot\"></view><view class=\"ds-pulse-dot\"></view></view>",
  259. "css": ".ds-loading { display: flex; justify-content: center; gap: 8rpx; padding: 60rpx 0; } .ds-pulse-dot { width: 9rpx; height: 9rpx; background: #cbd5e1; border-radius: 50%; animation: ds-pulse 1.2s ease-in-out infinite; } .ds-pulse-dot:nth-child(2) { animation-delay: 0.2s; } .ds-pulse-dot:nth-child(3) { animation-delay: 0.4s; } @keyframes ds-pulse { 0%, 80%, 100% { transform: scale(0.5); opacity: 0.4; } 40% { transform: scale(1); opacity: 1; } }"
  260. }
  261. ],
  262. "narrative": {
  263. "northStar": "The Warm Workshop",
  264. "overview": "haha-admin-mp 是 AI 智能零售柜系统的运营管理端。品牌语言与 haha-mp 消费者端一脉相承——琥珀暖金作为身份色,大面积留白托底,轻阴影赋予卡片可触感。设计不追求传统后台的功能堆砌,而是在移动端上呈现清晰、温暖、高效的信息结构。暖金不是装饰色,是信号色。它在关键操作(主按钮、激活态、扫码入口)上集中出现,其余区域用冷灰中性色后退,让操作者凭色彩就能感知界面优先级。",
  265. "keyCharacteristics": [
  266. "暖金信号:琥珀色承载关键操作和选中态,其余区域用冷灰后退",
  267. "轻提感:卡片统一使用 2rpx 模糊 12rpx 偏移的微阴影,暗示可点击性",
  268. "移动优先文字:最小字号不低於 22rpx,触控区域不小于 44x44pt",
  269. "8rpx 基准间距:所有间距为该基准的整数倍,拒绝随意值",
  270. "与 haha-mp 共享色彩基因"
  271. ],
  272. "rules": [
  273. { "name": "The Golden Signal Rule", "body": "暖金仅在交互关键点出现:主按钮、选中态、激活 Tab。其稀缺性制造信号效应。切勿将暖金用于大面积装饰或非交互内容。", "section": "colors" },
  274. { "name": "The Tinted Neutral Rule", "body": "所有中性色向暖金方向偏移 0.005-0.01 chroma。纯黑 #000000 和纯白 #ffffff 被禁用。视频背景使用 --bg-secondary 而非 #000。", "section": "colors" },
  275. { "name": "The Financial Data Rule", "body": "金额、统计数字永远使用 slate-text-primary,不使用红色或绿色。颜色仅携带语义状态(成功/失败),不携带价值判断。", "section": "colors" },
  276. { "name": "The 28rpx Anchor Rule", "body": "正文基线和主要控件字号均锚定在 28rpx。向上取 30/32/36rpx 做标题,向下取 22/24rpx 做辅助。绝不使用 26rpx——它作为无意义的中间值被禁用。", "section": "typography" },
  277. { "name": "The One Font Rule", "body": "整个系统使用单一字体栈。层次差异通过字号和 weight 表达,不通过字体切换表达。", "section": "typography" },
  278. { "name": "The Shadows-As-State Rule", "body": "阴影在静止态统一微弱,在交互态通过 opacity 而非 elevation 变化反馈。不做悬浮升起动画。FAB 的暖金 glow shadow 是唯一的例外。", "section": "elevation" }
  279. ],
  280. "dos": [
  281. "使用 8rpx 基准间距。所有 padding/margin/gap 必须是 8 的整数倍。",
  282. "使用 $spacing-N / $radius-* / $font-size-* SCSS token,不硬编码数值。",
  283. "为每个异步数据加载提供 loading 状态(pulse dots 或 spinner)。",
  284. "将暖金仅用于交互关键点。其力量来自克制。",
  285. "所有可点击卡片的 active 态使用 opacity: 0.7。",
  286. "页面使用 height: 100vh + flex column 布局,scroll-view 用 flex: 1; height: 0 填充剩余空间。",
  287. "固定底部元素使用 env(safe-area-inset-bottom) 留出安全区域。",
  288. "状态指示同时使用颜色 + 文字,不单纯依赖颜色(WCAG AA 兼容)。",
  289. "字体栈在所有页面 style 中统一声明为一行的 $font-stack 变量。"
  290. ],
  291. "donts": [
  292. "使用 #000000 或 #ffffff。中性色向暖金方向偏移 0.005-0.01 chroma。",
  293. "对财务数字使用红色或绿色。金额统计永远用 #1e293b。",
  294. "使用 border-left 或 border-right 大于 1px 做彩色侧边条纹装饰。",
  295. "使用渐变文字 (background-clip: text)。",
  296. "使用 26rpx 字号。字号体系中没有这个中间值。",
  297. "在页面中使用原生 <button> 组件 + &::after { border: none } hack。用 <view> 构建按钮。",
  298. "显示不完整功能。'开发中' 的 UI 要么隐藏,要么用 v-if 按数据可用性控制。",
  299. "硬编码背景色为 #000(如视频区)。使用 $bg-color-secondary。",
  300. "使用 min-height: 100vh 做页面布局。用 height: 100vh + flex column + flex:1 scroll-view。",
  301. "泄露传统 ERP 后台的痕迹:无密集表格、无多级菜单、无蓝白配色、无功能入口堆砌。"
  302. ]
  303. }
  304. }