{
  "schemaVersion": 2,
  "generatedAt": "2026-05-13T00:00:00.000Z",
  "title": "Design System: haha-admin-mp",
  "extensions": {
    "colorMeta": {
      "amber-primary": {
        "role": "primary",
        "displayName": "Amber Primary",
        "canonical": "oklch(78% 0.17 85)",
        "tonalRamp": [
          "oklch(20% 0.04 85)",
          "oklch(35% 0.08 85)",
          "oklch(48% 0.12 85)",
          "oklch(60% 0.15 85)",
          "oklch(70% 0.17 85)",
          "oklch(78% 0.17 85)",
          "oklch(88% 0.12 85)",
          "oklch(95% 0.04 85)"
        ]
      },
      "amber-bg": {
        "role": "primary-bg",
        "displayName": "Amber Background",
        "canonical": "oklch(97% 0.02 85)",
        "tonalRamp": [
          "oklch(98% 0.01 85)",
          "oklch(97% 0.02 85)",
          "oklch(96% 0.025 85)",
          "oklch(95% 0.03 85)",
          "oklch(94% 0.035 85)",
          "oklch(92% 0.05 85)",
          "oklch(90% 0.07 85)",
          "oklch(85% 0.1 85)"
        ]
      },
      "orange-accent": {
        "role": "secondary",
        "displayName": "Orange Accent",
        "canonical": "oklch(62% 0.2 50)",
        "tonalRamp": [
          "oklch(18% 0.05 50)",
          "oklch(30% 0.08 50)",
          "oklch(42% 0.12 50)",
          "oklch(52% 0.16 50)",
          "oklch(62% 0.2 50)",
          "oklch(72% 0.18 50)",
          "oklch(84% 0.1 50)",
          "oklch(94% 0.03 50)"
        ]
      },
      "green-success": {
        "role": "semantic",
        "displayName": "Green Success",
        "canonical": "oklch(62% 0.17 160)",
        "tonalRamp": [
          "oklch(18% 0.05 160)",
          "oklch(32% 0.08 160)",
          "oklch(45% 0.12 160)",
          "oklch(55% 0.15 160)",
          "oklch(62% 0.17 160)",
          "oklch(72% 0.15 160)",
          "oklch(84% 0.08 160)",
          "oklch(94% 0.03 160)"
        ]
      },
      "red-error": {
        "role": "semantic",
        "displayName": "Red Error",
        "canonical": "oklch(55% 0.21 25)",
        "tonalRamp": [
          "oklch(18% 0.06 25)",
          "oklch(28% 0.1 25)",
          "oklch(40% 0.15 25)",
          "oklch(50% 0.18 25)",
          "oklch(55% 0.21 25)",
          "oklch(65% 0.18 25)",
          "oklch(78% 0.1 25)",
          "oklch(93% 0.03 25)"
        ]
      },
      "amber-warning": {
        "role": "semantic",
        "displayName": "Amber Warning",
        "canonical": "oklch(68% 0.16 75)",
        "tonalRamp": [
          "oklch(18% 0.04 75)",
          "oklch(30% 0.07 75)",
          "oklch(44% 0.1 75)",
          "oklch(56% 0.13 75)",
          "oklch(68% 0.16 75)",
          "oklch(78% 0.14 75)",
          "oklch(86% 0.08 75)",
          "oklch(95% 0.03 75)"
        ]
      },
      "slate-text-primary": {
        "role": "neutral-text",
        "displayName": "Slate Text Primary",
        "canonical": "oklch(25% 0.01 260)",
        "tonalRamp": [
          "oklch(15% 0.01 260)",
          "oklch(20% 0.01 260)",
          "oklch(25% 0.01 260)",
          "oklch(35% 0.01 260)",
          "oklch(45% 0.01 260)",
          "oklch(60% 0.01 260)",
          "oklch(80% 0.005 85)",
          "oklch(94% 0.005 85)"
        ]
      },
      "ash-page-bg": {
        "role": "neutral-bg",
        "displayName": "Ash Page Background",
        "canonical": "oklch(97% 0.005 85)",
        "tonalRamp": [
          "oklch(99% 0.002 85)",
          "oklch(97% 0.005 85)",
          "oklch(95% 0.006 85)",
          "oklch(92% 0.007 85)",
          "oklch(88% 0.008 85)",
          "oklch(82% 0.008 85)",
          "oklch(72% 0.007 85)",
          "oklch(58% 0.006 85)"
        ]
      },
      "white-card-bg": {
        "role": "neutral-surface",
        "displayName": "White Card Background",
        "canonical": "oklch(100% 0.002 85)",
        "tonalRamp": [
          "oklch(100% 0 0)",
          "oklch(100% 0.002 85)",
          "oklch(98% 0.003 85)",
          "oklch(96% 0.004 85)",
          "oklch(93% 0.005 85)",
          "oklch(87% 0.006 85)",
          "oklch(76% 0.007 85)",
          "oklch(62% 0.006 85)"
        ]
      },
      "ash-border": {
        "role": "neutral-border",
        "displayName": "Ash Border",
        "canonical": "oklch(90% 0.005 260)",
        "tonalRamp": [
          "oklch(96% 0.003 260)",
          "oklch(93% 0.004 260)",
          "oklch(90% 0.005 260)",
          "oklch(85% 0.005 260)",
          "oklch(78% 0.005 260)",
          "oklch(68% 0.004 260)",
          "oklch(52% 0.003 260)",
          "oklch(32% 0.002 260)"
        ]
      }
    },
    "typographyMeta": {
      "display": { "displayName": "Display", "purpose": "订单金额、统计大数。仅在关键数据上出现。" },
      "headline": { "displayName": "Headline", "purpose": "页面标题、卡片标题、弹窗标题。" },
      "title": { "displayName": "Title", "purpose": "主要正文、列表项名称、标签。最广泛的字号。" },
      "body": { "displayName": "Body", "purpose": "正文信息、表单输入、描述文字。28rpx + 1.6 line-height。" },
      "label": { "displayName": "Label", "purpose": "标签、徽章、meta 文字。22rpx + 0.02em letter-spacing。" }
    },
    "shadows": [
      { "name": "card-rest", "value": "0 2rpx 12rpx rgba(0,0,0,0.05)", "purpose": "所有卡片和可交互表面在静止态的标准阴影。" },
      { "name": "card-subtle", "value": "0 2rpx 8rpx rgba(0,0,0,0.04)", "purpose": "轻量阴影，用于列表卡片之间的细微区分。" },
      { "name": "bottom-bar", "value": "0 -2rpx 12rpx rgba(0,0,0,0.05)", "purpose": "固定底部栏的方向性阴影，指向上方。" },
      { "name": "primary-glow", "value": "0 6rpx 20rpx rgba(255,193,7,0.4)", "purpose": "唯一彩色阴影。仅用于扫码FAB，暖金散射强调首要地位。" }
    ],
    "motion": [
      { "name": "ease-press", "value": "opacity 0.15s ease", "purpose": "所有按钮和可点击元素的 active 态反馈。通过 opacity 变化而非 layout property 动画。" },
      { "name": "ease-pulse", "value": "1.2s ease-in-out infinite", "purpose": "加载 pulse dots 的序列动画。不适用 ease-out-quart 因其为循环动画。" },
      { "name": "ease-spin", "value": "1s linear infinite", "purpose": "加载 spinner 的旋转动画。" }
    ],
    "breakpoints": [
      { "name": "mobile", "value": "375px-414px", "purpose": "微信小程序标准视口宽度。" }
    ]
  },
  "components": [
    {
      "name": "Primary Button",
      "kind": "button",
      "refersTo": "button-primary",
      "description": "页面级主操作：保存、退款、确认。暖金填充胶囊。",
      "html": "<view class=\"ds-btn-primary\"><text class=\"ds-btn-primary-text\">保存</text></view>",
      "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; }"
    },
    {
      "name": "Secondary Action Button",
      "kind": "button",
      "refersTo": "button-secondary",
      "description": "卡片内次级操作：查看详情、筛选、复制。填充底色无边框。",
      "html": "<view class=\"ds-btn-secondary\"><text class=\"ds-btn-secondary-text\">查看详情</text></view>",
      "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; }"
    },
    {
      "name": "Surface Card",
      "kind": "card",
      "refersTo": "card-surface",
      "description": "信息容器。白色背景，微阴影，中等圆角。用于列表项和内容区。",
      "html": "<view class=\"ds-card\"><text class=\"ds-card-heading\">标题</text><text class=\"ds-card-body\">内容文本行，展示关键信息。</text></view>",
      "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; }"
    },
    {
      "name": "Status Tag - Success",
      "kind": "chip",
      "refersTo": "status-tag-success",
      "description": "成功/正常/完成状态标签。绿底绿字。",
      "html": "<view class=\"ds-tag ds-tag-success\"><text>已完成</text></view>",
      "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; }"
    },
    {
      "name": "Status Tag - Warning",
      "kind": "chip",
      "refersTo": "status-tag-warning",
      "description": "待处理/未支付状态标签。琥珀底琥珀字。",
      "html": "<view class=\"ds-tag ds-tag-warning\"><text>待支付</text></view>",
      "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; }"
    },
    {
      "name": "Status Tag - Error",
      "kind": "chip",
      "refersTo": "status-tag-error",
      "description": "失败/退款/故障状态标签。红底红字。",
      "html": "<view class=\"ds-tag ds-tag-error\"><text>已退款</text></view>",
      "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; }"
    },
    {
      "name": "Navigation Bar",
      "kind": "nav",
      "refersTo": null,
      "description": "固定顶部导航栏。居中标题，左侧返回箭头，支持安全区域。",
      "html": "<view class=\"ds-navbar\"><view class=\"ds-navback\"><view class=\"ds-navback-arrow\"></view></view><text class=\"ds-navtitle\">页面标题</text></view>",
      "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; }"
    },
    {
      "name": "Tab Bar",
      "kind": "nav",
      "refersTo": null,
      "description": "固定底部标签栏。4 个标准 Tab 围绕中央扫码 FAB。激活态变暖金。",
      "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>",
      "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; }"
    },
    {
      "name": "Text Input Field",
      "kind": "input",
      "refersTo": null,
      "description": "标准输入框。灰底，圆角，暖金 focus 边框。",
      "html": "<input class=\"ds-input\" placeholder=\"请输入姓名\" />",
      "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; }"
    },
    {
      "name": "Loading Pulse Dots",
      "kind": "custom",
      "refersTo": null,
      "description": "页面级加载指示器。三个序列脉冲圆点。",
      "html": "<view class=\"ds-loading\"><view class=\"ds-pulse-dot\"></view><view class=\"ds-pulse-dot\"></view><view class=\"ds-pulse-dot\"></view></view>",
      "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; } }"
    }
  ],
  "narrative": {
    "northStar": "The Warm Workshop",
    "overview": "haha-admin-mp 是 AI 智能零售柜系统的运营管理端。品牌语言与 haha-mp 消费者端一脉相承——琥珀暖金作为身份色，大面积留白托底，轻阴影赋予卡片可触感。设计不追求传统后台的功能堆砌，而是在移动端上呈现清晰、温暖、高效的信息结构。暖金不是装饰色，是信号色。它在关键操作（主按钮、激活态、扫码入口）上集中出现，其余区域用冷灰中性色后退，让操作者凭色彩就能感知界面优先级。",
    "keyCharacteristics": [
      "暖金信号：琥珀色承载关键操作和选中态，其余区域用冷灰后退",
      "轻提感：卡片统一使用 2rpx 模糊 12rpx 偏移的微阴影，暗示可点击性",
      "移动优先文字：最小字号不低於 22rpx，触控区域不小于 44x44pt",
      "8rpx 基准间距：所有间距为该基准的整数倍，拒绝随意值",
      "与 haha-mp 共享色彩基因"
    ],
    "rules": [
      { "name": "The Golden Signal Rule", "body": "暖金仅在交互关键点出现：主按钮、选中态、激活 Tab。其稀缺性制造信号效应。切勿将暖金用于大面积装饰或非交互内容。", "section": "colors" },
      { "name": "The Tinted Neutral Rule", "body": "所有中性色向暖金方向偏移 0.005-0.01 chroma。纯黑 #000000 和纯白 #ffffff 被禁用。视频背景使用 --bg-secondary 而非 #000。", "section": "colors" },
      { "name": "The Financial Data Rule", "body": "金额、统计数字永远使用 slate-text-primary，不使用红色或绿色。颜色仅携带语义状态（成功/失败），不携带价值判断。", "section": "colors" },
      { "name": "The 28rpx Anchor Rule", "body": "正文基线和主要控件字号均锚定在 28rpx。向上取 30/32/36rpx 做标题，向下取 22/24rpx 做辅助。绝不使用 26rpx——它作为无意义的中间值被禁用。", "section": "typography" },
      { "name": "The One Font Rule", "body": "整个系统使用单一字体栈。层次差异通过字号和 weight 表达，不通过字体切换表达。", "section": "typography" },
      { "name": "The Shadows-As-State Rule", "body": "阴影在静止态统一微弱，在交互态通过 opacity 而非 elevation 变化反馈。不做悬浮升起动画。FAB 的暖金 glow shadow 是唯一的例外。", "section": "elevation" }
    ],
    "dos": [
      "使用 8rpx 基准间距。所有 padding/margin/gap 必须是 8 的整数倍。",
      "使用 $spacing-N / $radius-* / $font-size-* SCSS token，不硬编码数值。",
      "为每个异步数据加载提供 loading 状态（pulse dots 或 spinner）。",
      "将暖金仅用于交互关键点。其力量来自克制。",
      "所有可点击卡片的 active 态使用 opacity: 0.7。",
      "页面使用 height: 100vh + flex column 布局，scroll-view 用 flex: 1; height: 0 填充剩余空间。",
      "固定底部元素使用 env(safe-area-inset-bottom) 留出安全区域。",
      "状态指示同时使用颜色 + 文字，不单纯依赖颜色（WCAG AA 兼容）。",
      "字体栈在所有页面 style 中统一声明为一行的 $font-stack 变量。"
    ],
    "donts": [
      "使用 #000000 或 #ffffff。中性色向暖金方向偏移 0.005-0.01 chroma。",
      "对财务数字使用红色或绿色。金额统计永远用 #1e293b。",
      "使用 border-left 或 border-right 大于 1px 做彩色侧边条纹装饰。",
      "使用渐变文字 (background-clip: text)。",
      "使用 26rpx 字号。字号体系中没有这个中间值。",
      "在页面中使用原生 <button> 组件 + &::after { border: none } hack。用 <view> 构建按钮。",
      "显示不完整功能。'开发中' 的 UI 要么隐藏，要么用 v-if 按数据可用性控制。",
      "硬编码背景色为 #000（如视频区）。使用 $bg-color-secondary。",
      "使用 min-height: 100vh 做页面布局。用 height: 100vh + flex column + flex:1 scroll-view。",
      "泄露传统 ERP 后台的痕迹：无密集表格、无多级菜单、无蓝白配色、无功能入口堆砌。"
    ]
  }
}
