@tfdesign/b-end 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/AI_READ_FIRST.md +131 -0
  2. package/LICENSE +21 -0
  3. package/README.md +353 -0
  4. package/package.json +67 -0
  5. package/scripts/check-tfds-contract.mjs +334 -0
  6. package/scripts/check-tfds-integration.mjs +263 -0
  7. package/scripts/postinstall-cursor-skill.mjs +382 -0
  8. package/scripts/setup.mjs +520 -0
  9. package/skills/tfds/CHECKLIST.md +205 -0
  10. package/skills/tfds/COMMON_FAILURES.md +238 -0
  11. package/skills/tfds/DESIGN_PRINCIPLES.md +477 -0
  12. package/skills/tfds/GLOBAL_DESIGN_RULES.md +636 -0
  13. package/skills/tfds/LAYOUT_RECIPES.md +140 -0
  14. package/skills/tfds/LAYOUT_RULES.md +1355 -0
  15. package/skills/tfds/PAGE_ARCHETYPES.md +201 -0
  16. package/skills/tfds/SKILL.md +188 -0
  17. package/skills/tfds/components.index.json +7305 -0
  18. package/skills/tfds/components.summary.json +1809 -0
  19. package/src/_b_end_runtime/components/AiSuggestionShared.jsx +166 -0
  20. package/src/_b_end_runtime/components/Avatar.jsx +325 -0
  21. package/src/_b_end_runtime/components/Avatar.tokens.js +76 -0
  22. package/src/_b_end_runtime/components/AvatarGridPreview.jsx +56 -0
  23. package/src/_b_end_runtime/components/AvatarGroup.jsx +80 -0
  24. package/src/_b_end_runtime/components/AvatarGroup.tokens.js +28 -0
  25. package/src/_b_end_runtime/components/Button.jsx +144 -0
  26. package/src/_b_end_runtime/components/Button.tokens.js +90 -0
  27. package/src/_b_end_runtime/components/Card.jsx +460 -0
  28. package/src/_b_end_runtime/components/Card.tokens.js +124 -0
  29. package/src/_b_end_runtime/components/CardPreview.jsx +51 -0
  30. package/src/_b_end_runtime/components/ChatBubble.jsx +384 -0
  31. package/src/_b_end_runtime/components/ChatBubble.tokens.js +60 -0
  32. package/src/_b_end_runtime/components/ChatBubblePreview.jsx +129 -0
  33. package/src/_b_end_runtime/components/ChatInput.jsx +1399 -0
  34. package/src/_b_end_runtime/components/ChatInput.tokens.js +75 -0
  35. package/src/_b_end_runtime/components/ChatMessage.jsx +2215 -0
  36. package/src/_b_end_runtime/components/ChatMessage.tokens.js +257 -0
  37. package/src/_b_end_runtime/components/ChatMessagePreview.jsx +388 -0
  38. package/src/_b_end_runtime/components/Checkbox.jsx +317 -0
  39. package/src/_b_end_runtime/components/Checkbox.tokens.js +59 -0
  40. package/src/_b_end_runtime/components/ConversationList.jsx +1264 -0
  41. package/src/_b_end_runtime/components/ConversationList.tokens.js +135 -0
  42. package/src/_b_end_runtime/components/ConversationListPreview.jsx +108 -0
  43. package/src/_b_end_runtime/components/CustomerServiceWorkspaceFrame.jsx +324 -0
  44. package/src/_b_end_runtime/components/CustomerServiceWorkspaceFrame.tokens.js +69 -0
  45. package/src/_b_end_runtime/components/DatePicker.jsx +739 -0
  46. package/src/_b_end_runtime/components/DatePicker.tokens.js +99 -0
  47. package/src/_b_end_runtime/components/Empty.jsx +141 -0
  48. package/src/_b_end_runtime/components/Empty.tokens.js +40 -0
  49. package/src/_b_end_runtime/components/Form.jsx +609 -0
  50. package/src/_b_end_runtime/components/Form.tokens.js +77 -0
  51. package/src/_b_end_runtime/components/FormFieldStack.jsx +123 -0
  52. package/src/_b_end_runtime/components/FormFieldStack.tokens.js +12 -0
  53. package/src/_b_end_runtime/components/FormTitle.jsx +119 -0
  54. package/src/_b_end_runtime/components/FormTitle.tokens.js +87 -0
  55. package/src/_b_end_runtime/components/FullScreenPage.jsx +97 -0
  56. package/src/_b_end_runtime/components/FullScreenPage.tokens.js +19 -0
  57. package/src/_b_end_runtime/components/Icon.jsx +172 -0
  58. package/src/_b_end_runtime/components/Icon.tokens.js +26 -0
  59. package/src/_b_end_runtime/components/IconGridPreview.jsx +277 -0
  60. package/src/_b_end_runtime/components/InfoDisplayPanel.jsx +620 -0
  61. package/src/_b_end_runtime/components/InfoDisplayPanel.tokens.js +71 -0
  62. package/src/_b_end_runtime/components/InfoDisplayPanelPreview.jsx +133 -0
  63. package/src/_b_end_runtime/components/Input.jsx +258 -0
  64. package/src/_b_end_runtime/components/Input.tokens.js +68 -0
  65. package/src/_b_end_runtime/components/InputNumber.jsx +242 -0
  66. package/src/_b_end_runtime/components/InputNumber.tokens.js +55 -0
  67. package/src/_b_end_runtime/components/Modal.jsx +155 -0
  68. package/src/_b_end_runtime/components/Modal.tokens.js +73 -0
  69. package/src/_b_end_runtime/components/NavBar.jsx +842 -0
  70. package/src/_b_end_runtime/components/NavBar.tokens.js +97 -0
  71. package/src/_b_end_runtime/components/NavBarPreview.jsx +11 -0
  72. package/src/_b_end_runtime/components/Radio.jsx +227 -0
  73. package/src/_b_end_runtime/components/Radio.tokens.js +59 -0
  74. package/src/_b_end_runtime/components/Select.jsx +766 -0
  75. package/src/_b_end_runtime/components/Select.tokens.js +99 -0
  76. package/src/_b_end_runtime/components/Sheet.jsx +132 -0
  77. package/src/_b_end_runtime/components/Sheet.tokens.js +61 -0
  78. package/src/_b_end_runtime/components/Slider.jsx +346 -0
  79. package/src/_b_end_runtime/components/Slider.tokens.js +47 -0
  80. package/src/_b_end_runtime/components/Switch.jsx +124 -0
  81. package/src/_b_end_runtime/components/Switch.tokens.js +38 -0
  82. package/src/_b_end_runtime/components/Table.jsx +1338 -0
  83. package/src/_b_end_runtime/components/Table.tokens.js +147 -0
  84. package/src/_b_end_runtime/components/TablePreview.jsx +599 -0
  85. package/src/_b_end_runtime/components/Tabs.jsx +149 -0
  86. package/src/_b_end_runtime/components/Tabs.tokens.js +102 -0
  87. package/src/_b_end_runtime/components/Tag.jsx +199 -0
  88. package/src/_b_end_runtime/components/Tag.tokens.js +171 -0
  89. package/src/_b_end_runtime/components/TagBar.jsx +1134 -0
  90. package/src/_b_end_runtime/components/TagBar.tokens.js +75 -0
  91. package/src/_b_end_runtime/components/TagGridPreview.jsx +23 -0
  92. package/src/_b_end_runtime/components/TagInput.jsx +382 -0
  93. package/src/_b_end_runtime/components/TagInput.tokens.js +52 -0
  94. package/src/_b_end_runtime/components/TextArea.jsx +363 -0
  95. package/src/_b_end_runtime/components/TextArea.tokens.js +65 -0
  96. package/src/_b_end_runtime/components/TimePicker.jsx +444 -0
  97. package/src/_b_end_runtime/components/TimePicker.tokens.js +77 -0
  98. package/src/_b_end_runtime/components/Toast.jsx +120 -0
  99. package/src/_b_end_runtime/components/Toast.tokens.js +146 -0
  100. package/src/_b_end_runtime/components/Tooltip.jsx +282 -0
  101. package/src/_b_end_runtime/components/Tooltip.tokens.js +48 -0
  102. package/src/_b_end_runtime/components/TooltipPreview.jsx +50 -0
  103. package/src/_b_end_runtime/components/Upload.jsx +455 -0
  104. package/src/_b_end_runtime/components/Upload.tokens.js +47 -0
  105. package/src/_b_end_runtime/components/avatar-assets/avatar-default.png +0 -0
  106. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-1.png +0 -0
  107. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-2.png +0 -0
  108. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-3.png +0 -0
  109. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-4.png +0 -0
  110. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-5.png +0 -0
  111. package/src/_b_end_runtime/components/empty-assets/administrator-1.svg +40 -0
  112. package/src/_b_end_runtime/components/empty-assets/administrator-2.svg +33 -0
  113. package/src/_b_end_runtime/components/empty-assets/construction.svg +33 -0
  114. package/src/_b_end_runtime/components/empty-assets/failure.svg +49 -0
  115. package/src/_b_end_runtime/components/empty-assets/idle.svg +34 -0
  116. package/src/_b_end_runtime/components/empty-assets/no-access.svg +36 -0
  117. package/src/_b_end_runtime/components/empty-assets/no-content.svg +77 -0
  118. package/src/_b_end_runtime/components/empty-assets/no-result.svg +61 -0
  119. package/src/_b_end_runtime/components/empty-assets/not-found.svg +46 -0
  120. package/src/_b_end_runtime/components/empty-assets/success.svg +38 -0
  121. package/src/_b_end_runtime/components/file-type-assets/batch-report.png +0 -0
  122. package/src/_b_end_runtime/components/file-type-assets/catcat.svg +21 -0
  123. package/src/_b_end_runtime/components/file-type-assets/code.png +0 -0
  124. package/src/_b_end_runtime/components/file-type-assets/conversation.png +0 -0
  125. package/src/_b_end_runtime/components/file-type-assets/document.png +0 -0
  126. package/src/_b_end_runtime/components/file-type-assets/feishu-card.png +0 -0
  127. package/src/_b_end_runtime/components/file-type-assets/feishu-sheet.png +0 -0
  128. package/src/_b_end_runtime/components/file-type-assets/feishu.png +0 -0
  129. package/src/_b_end_runtime/components/file-type-assets/image.png +0 -0
  130. package/src/_b_end_runtime/components/file-type-assets/index.js +105 -0
  131. package/src/_b_end_runtime/components/file-type-assets/knowledge.png +0 -0
  132. package/src/_b_end_runtime/components/file-type-assets/pdf.png +0 -0
  133. package/src/_b_end_runtime/components/file-type-assets/pe.png +0 -0
  134. package/src/_b_end_runtime/components/file-type-assets/strategy.png +0 -0
  135. package/src/_b_end_runtime/components/file-type-assets/table.png +0 -0
  136. package/src/_b_end_runtime/components/file-type-assets/webpage.png +0 -0
  137. package/src/_b_end_runtime/components/file-type-assets/xmind.png +0 -0
  138. package/src/_b_end_runtime/components/icons/icon-data.js +12496 -0
  139. package/src/_b_end_runtime/components/nav-bar-assets/bytehi-logo-mark.svg +21 -0
  140. package/src/_b_end_runtime/components/table-assets/avatar.png +0 -0
  141. package/src/_b_end_runtime/components/table-assets/button.png +0 -0
  142. package/src/_b_end_runtime/components/table-assets/icon-chevron-down.png +0 -0
  143. package/src/_b_end_runtime/components/table-cell-assets/avatar.png +0 -0
  144. package/src/_b_end_runtime/components/table-cell-assets/button.png +0 -0
  145. package/src/_b_end_runtime/components/table-cell-assets/checkbox.png +0 -0
  146. package/src/_b_end_runtime/components/table-cell-assets/icon-chevron-right.png +0 -0
  147. package/src/_b_end_runtime/components/table-cell-assets/icon.png +0 -0
  148. package/src/_b_end_runtime/components/table-cell-assets/semi-icons-handle.png +0 -0
  149. package/src/_b_end_runtime/components/table-cell-assets/semi-icons-tree-triangle-right.png +0 -0
  150. package/src/_b_end_runtime/components/table-cell-assets/switch.png +0 -0
  151. package/src/_b_end_runtime/components/tagShared.js +3 -0
  152. package/src/_b_end_runtime/components/team-avatar-assets/chengcheng-murphy.png +0 -0
  153. package/src/_b_end_runtime/components/team-avatar-assets/duan-ran.png +0 -0
  154. package/src/_b_end_runtime/components/team-avatar-assets/guo-zhezhi.png +0 -0
  155. package/src/_b_end_runtime/components/team-avatar-assets/li-siru.png +0 -0
  156. package/src/_b_end_runtime/components/team-avatar-assets/liu-delin.png +0 -0
  157. package/src/_b_end_runtime/components.js +3499 -0
  158. package/src/_b_end_runtime/index.js +9 -0
  159. package/src/_b_end_runtime/page-patterns/BasePageFramePattern.jsx +395 -0
  160. package/src/_b_end_runtime/page-patterns/ChatConversationPattern.jsx +989 -0
  161. package/src/_b_end_runtime/page-patterns/ChatHomePagePattern.jsx +281 -0
  162. package/src/_b_end_runtime/page-patterns/CopilotPagePattern.jsx +380 -0
  163. package/src/_b_end_runtime/page-patterns/CustomerServiceWorkspaceFramePattern.jsx +392 -0
  164. package/src/_b_end_runtime/page-patterns/IMConversationPattern.jsx +590 -0
  165. package/src/_b_end_runtime/page-patterns/McpManagementPage.jsx +237 -0
  166. package/src/_b_end_runtime/page-patterns/StrategyListPage.jsx +189 -0
  167. package/src/_b_end_runtime/page-patterns/TabTopBarListPage.jsx +594 -0
  168. package/src/_b_end_runtime/page-patterns/VariableManagementPage.jsx +87 -0
  169. package/src/_b_end_runtime/page-patterns/pageListShared.jsx +177 -0
  170. package/src/_b_end_runtime/patterns.js +428 -0
  171. package/src/_b_end_runtime/preview-registry.jsx +4719 -0
  172. package/src/_b_end_runtime/teamMembers.js +56 -0
  173. package/src/_b_end_runtime/tokens.js +500 -0
  174. package/src/index.d.ts +1073 -0
  175. package/src/index.js +52 -0
  176. package/theme.css +350 -0
@@ -0,0 +1,56 @@
1
+ import liuDelinAvatar from './components/team-avatar-assets/liu-delin.png';
2
+ import liSiruAvatar from './components/team-avatar-assets/li-siru.png';
3
+ import duanRanAvatar from './components/team-avatar-assets/duan-ran.png';
4
+ import chengchengMurphyAvatar from './components/team-avatar-assets/chengcheng-murphy.png';
5
+ import guoZhezhiAvatar from './components/team-avatar-assets/guo-zhezhi.png';
6
+
7
+ export const TEAM_MEMBERS = [
8
+ { id: 'li-siru', name: '李思儒', avatarSrc: liSiruAvatar },
9
+ { id: 'chengcheng-murphy', name: '程程murphy', avatarSrc: chengchengMurphyAvatar },
10
+ { id: 'liu-delin', name: '刘德琳', avatarSrc: liuDelinAvatar },
11
+ { id: 'duan-ran', name: '段然', avatarSrc: duanRanAvatar },
12
+ { id: 'guo-zhezhi', name: '郭泽智', avatarSrc: guoZhezhiAvatar },
13
+ ];
14
+
15
+ export const DEFAULT_TEAM_MEMBER = TEAM_MEMBERS[4];
16
+ export const TEAM_MEMBER_AVATAR_SRCS = TEAM_MEMBERS.map((member) => member.avatarSrc);
17
+
18
+ export const TEAM_MEMBER_BY_NAME = Object.fromEntries(
19
+ TEAM_MEMBERS.map((member) => [member.name, member]),
20
+ );
21
+
22
+ export function getTeamMemberByIndex(index = 0) {
23
+ if (TEAM_MEMBERS.length === 0) return null;
24
+ const normalizedIndex = Math.abs(Number(index) || 0) % TEAM_MEMBERS.length;
25
+ return TEAM_MEMBERS[normalizedIndex];
26
+ }
27
+
28
+ export function getTeamMemberBySeed(seed = 0) {
29
+ if (typeof seed === 'number') {
30
+ return getTeamMemberByIndex(seed);
31
+ }
32
+
33
+ const input = String(seed || '');
34
+ let hash = 0;
35
+ for (let i = 0; i < input.length; i += 1) {
36
+ hash = (hash * 31 + input.charCodeAt(i)) >>> 0;
37
+ }
38
+ return getTeamMemberByIndex(hash);
39
+ }
40
+
41
+ export function getTeamAvatarBySeed(seed = 0) {
42
+ return getTeamMemberBySeed(seed)?.avatarSrc || DEFAULT_TEAM_MEMBER.avatarSrc;
43
+ }
44
+
45
+ export function getRandomTeamMember() {
46
+ return getTeamMemberByIndex(Math.floor(Math.random() * TEAM_MEMBERS.length));
47
+ }
48
+
49
+ export function getRandomTeamAvatarSrc() {
50
+ return getRandomTeamMember()?.avatarSrc || DEFAULT_TEAM_MEMBER.avatarSrc;
51
+ }
52
+
53
+ export function getTeamMemberByName(name) {
54
+ if (!name) return null;
55
+ return TEAM_MEMBER_BY_NAME[name] || null;
56
+ }
@@ -0,0 +1,500 @@
1
+ // ============================================================
2
+ // B端设计系统 — Token 规范
3
+ // 结构参考 Tailwind:Primitives 为原始刻度,Semantic Mapping 为语义桥接
4
+ // ============================================================
5
+
6
+ // ── Primitives ──────────────────────────────────────────────
7
+ // 原始刻度层,AI 直接消费。命名、刻度与 Tailwind 对齐。
8
+
9
+ export const TOKEN_COLORS = {
10
+ brand: { label: 'Brand', shades: { 50:'#EAFAF6',100:'#CFF3EA',200:'#A8E8D7',300:'#87DEC9',400:'#6BD8BF',500:'#56D3BC',600:'#32C4AC',700:'#18B49D',800:'#129683',900:'#0D786A',950:'#053E3A' }},
11
+ blueGrey: { label: 'Blue Grey', shades: { 50:'#FCFCFD',100:'#F9FAFB',200:'#F2F4F7',300:'#E4E7EC',400:'#D0D5DD',500:'#98A2B3',600:'#667085',700:'#475467',800:'#344054',900:'#182230',950:'#0D1321' }},
12
+ grey: { label: 'Grey', shades: { 50:'#F9F9F9',100:'#E6E7EA',200:'#C6C7CD',300:'#A7A8B0',400:'#878892',500:'#6B6C75',600:'#555661',700:'#41424C',800:'#2E2F38',900:'#1C1C23',950:'#111116' }},
13
+ blue: { label: 'Blue', shades: { 50:'#ECF6FE',100:'#CFE9FE',200:'#9FD1FC',300:'#70B8FB',400:'#429EF9',500:'#1482F8',600:'#0B69D4',700:'#0451B1',800:'#003D8D',900:'#002C69',950:'#001A36' }},
14
+ indigo: { label: 'Indigo', shades: { 50:'#ECEFF7',100:'#D1D6F0',200:'#A6B1E1',300:'#7F8ED1',400:'#5D6DC2',500:'#3E4FB3',600:'#32409F',700:'#28338A',800:'#1E2776',900:'#161C61',950:'#0D1240' }},
15
+ lightBlue: { label: 'Light Blue', shades: { 50:'#F0F7FB',100:'#DCEEFA',200:'#9CD8F7',300:'#6FC8F4',400:'#3FB6F0',500:'#139FEC',600:'#0A81C5',700:'#0365A9',800:'#034A83',900:'#0A3550',950:'#061F30' }},
16
+ green: { label: 'Green', shades: { 50:'#F0FDF4',100:'#D0F8D1',200:'#A6F1A7',300:'#7FE182',400:'#5ECE62',500:'#3EB346',600:'#329538',700:'#27772F',800:'#1D5A24',900:'#123C18',950:'#09220D' }},
17
+ lightGreen: { label: 'Light Green', shades: { 50:'#F6FAF0',100:'#E4EECF',200:'#C8E09E',300:'#AFD16E',400:'#97BF41',500:'#7FAE18',600:'#6A9215',700:'#577713',800:'#455E12',900:'#354810',950:'#1F2A09' }},
18
+ lime: { label: 'Lime', shades: { 50:'#F3FAE8',100:'#E5F5C8',200:'#CFEC95',300:'#BDE266',400:'#AED93A',500:'#A3CF11',600:'#85AD0C',700:'#688A09',800:'#4C6705',900:'#314503',950:'#1F2A02' }},
19
+ cyan: { label: 'Cyan', shades: { 50:'#EAF9FA',100:'#C2F0F3',200:'#8AE3E8',300:'#58D4DC',400:'#30C4CF',500:'#14B1BE',600:'#0E94A0',700:'#0A7782',800:'#075A64',900:'#043F47',950:'#022429' }},
20
+ red: { label: 'Red', shades: { 50:'#FEF2F1',100:'#FCD9D7',200:'#F9ACA7',300:'#F6837B',400:'#F35F55',500:'#F74331',600:'#D32E24',700:'#AD201A',800:'#861613',900:'#600E0D',950:'#3B0706' }},
21
+ orange: { label: 'Orange', shades: { 50:'#FFF5EE',100:'#FEE1CA',200:'#FDC592',300:'#FBAA5E',400:'#FA9332',500:'#FA8B14',600:'#D17310',700:'#A85B0D',800:'#80440A',900:'#5A3008',950:'#351B04' }},
22
+ yellow: { label: 'Yellow', shades: { 50:'#FEFDEC',100:'#FEFACF',200:'#FCF29F',300:'#FBE870',400:'#F9DA42',500:'#F8C914',600:'#CF9D0F',700:'#A5760A',800:'#7C5206',900:'#533203',950:'#331F02' }},
23
+ amber: { label: 'Amber', shades: { 50:'#FFFAEB',100:'#FEF0C7',200:'#FEDF89',300:'#FEC84B',400:'#FDB022',500:'#F79009',600:'#DC6803',700:'#B54708',800:'#93370D',900:'#7A2E0E',950:'#4A1A06' }},
24
+ pink: { label: 'Pink', shades: { 50:'#FDEDF1',100:'#FAD2DC',200:'#F5A7BD',300:'#F17DA2',400:'#EC558A',500:'#E72E75',600:'#C32165',700:'#A01654',800:'#7C0E43',900:'#580731',950:'#360420' }},
25
+ violet: { label: 'Violet', shades: { 50:'#F1EEF9',100:'#DCD4F3',200:'#BBACE8',300:'#9E86DC',400:'#8464D1',500:'#6D45C5',600:'#6039B1',700:'#542D9C',800:'#482388',900:'#3C1B73',950:'#28124D' }},
26
+ purple: { label: 'Purple', shades: { 50:'#F7EAF7',100:'#F0CCF0',200:'#DF9DE1',300:'#CC73D1',400:'#B74EC2',500:'#A22DB3',600:'#8B239F',700:'#751A8A',800:'#5F1376',900:'#4B0D61',950:'#31083F' }},
27
+ };
28
+
29
+ // 图表 / 数据可视化专用色序列,不参与普通 UI 组件配色
30
+ export const TOKEN_DATA_COLORS = [
31
+ '#24CDA5', '#FF8F52', '#D93B95', '#835FD8', '#3F81EB', '#63D1E0',
32
+ '#F2496F', '#6EA1DA', '#B399FE', '#FC7E90', '#C6E360', '#FEC849',
33
+ ];
34
+
35
+ // 组件特化色:仅供特定组件使用的"非通用"色阶。
36
+ // 命名空间共用 --color-*,让 Tailwind 短写法(bg-robot-500、fill-robot-50)照常可用,
37
+ // 但不进 TOKEN_COLORS 通用调色板,避免被误用为基础色相 / 污染色板视觉。
38
+ // 新增条目时:每条必须有 usedBy,写明它服务于哪些组件(AI / 设计师可一眼追溯归属)。
39
+ export const TOKEN_COMPONENT_COLORS = {
40
+ robot: {
41
+ label: 'Robot',
42
+ usedBy: ['Avatar'],
43
+ desc: '机器人头像插画专用配色(底色 / 耳朵底色 / 主色 / 五官色)',
44
+ shades: { 50: '#FCFCFC', 100: '#EDEDED', 500: '#24B9D9', 900: '#000000' },
45
+ },
46
+ };
47
+
48
+ export const TOKEN_SPACING = {
49
+ '0': '0px',
50
+ '0_5': '2px',
51
+ '1': '4px',
52
+ '2': '8px',
53
+ 'avatar-group-overlap': '10px',
54
+ '3': '12px',
55
+ '4': '16px',
56
+ '5': '20px',
57
+ '6': '24px',
58
+ '7': '28px',
59
+ '8': '32px',
60
+ '10': '40px',
61
+ '12': '48px',
62
+ '16': '64px',
63
+ };
64
+
65
+ export const TOKEN_RADIUS = {
66
+ none: '0px', avatar: '3px', sm: '4px', md: '8px', lg: '12px', xl: '16px', card: '20px', '2xl': '24px', full: '9999px',
67
+ };
68
+
69
+ export const TOKEN_FONT_SIZE = {
70
+ xs: '0.75rem',
71
+ sm: '0.875rem',
72
+ base: '1rem',
73
+ lg: '1.125rem',
74
+ xl: '1.25rem',
75
+ '2xl': '1.5rem',
76
+ '3xl': '1.875rem',
77
+ '4xl': '2.25rem',
78
+ '5xl': '3rem',
79
+ };
80
+
81
+ export const TOKEN_FONT_SIZE_PX = {
82
+ xs: 12, sm: 14, base: 16, lg: 18, xl: 20, '2xl': 24, '3xl': 30, '4xl': 36, '5xl': 48,
83
+ };
84
+
85
+ export const TOKEN_FONT_STACK = 'Inter, "PingFang SC", "PingFang TC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif';
86
+
87
+ export const TOKEN_FONT_BY_SCRIPT = {
88
+ latin: { label: '英文 Inter', css: 'Inter, system-ui, sans-serif' },
89
+ cjk: { label: '中文 苹方', css: '"PingFang SC", "PingFang TC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif' },
90
+ };
91
+
92
+ export const TOKEN_FONT_WEIGHT = {
93
+ normal: 400,
94
+ medium: 500,
95
+ semibold: 600,
96
+ bold: 700,
97
+ };
98
+
99
+ export const TOKEN_LINE_HEIGHT = {
100
+ '4': '16px',
101
+ '5': '20px',
102
+ 'card-copy': '21px',
103
+ 'card-title': '22px',
104
+ };
105
+
106
+ export const TOKEN_SIZE = {
107
+ 'card-width': '400px',
108
+ 'card-min-height': '201px',
109
+ 'chat-bubble-max': '500px',
110
+ 'icon-14': '14px',
111
+ 'control-sm': '24px',
112
+ 'control-md': '36px',
113
+ 'input-width': '300px',
114
+ };
115
+
116
+ export const TOKEN_LETTER_SPACING = {
117
+ tighter: '-0.05em', tight: '-0.025em', normal: '0em', wide: '0.025em', wider: '0.05em', widest: '0.1em',
118
+ };
119
+
120
+ // 基础阴影刻度沿用 Tailwind;业务语义阴影(如 card / list)也统一从这里输出。
121
+ export const TOKEN_SHADOWS = {
122
+ none: '0 0 #0000',
123
+ sm: '0 1px 2px 0 rgba(0,0,0,0.05)',
124
+ DEFAULT: '0 1px 3px 0 rgba(0,0,0,0.1), 0 1px 2px -1px rgba(0,0,0,0.1)',
125
+ md: '0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1)',
126
+ lg: '0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1)',
127
+ xl: '0 20px 25px -5px rgba(0,0,0,0.1), 0 8px 10px -6px rgba(0,0,0,0.1)',
128
+ '2xl': '0 25px 50px -12px rgba(0,0,0,0.25)',
129
+ card: '0 30px 50px 0 rgba(0,9,36,0.05)',
130
+ list: '0 0 16px 0 rgba(101,115,137,0.06)',
131
+ };
132
+
133
+ export const TOKEN_GRADIENTS = {
134
+ dark: {
135
+ label: 'Dark',
136
+ desc: '深色 AI 背景渐变,适合暗色 Hero、封面视觉、深色强调型容器',
137
+ css: 'linear-gradient(74deg, rgba(134,255,197,0.4) 1.5%, transparent 50%), linear-gradient(250deg, rgba(255,158,44,0.28) 11%, transparent 52%), linear-gradient(101deg, #34423B 14%, #16141F 104%)',
138
+ },
139
+ 'ai-fill-1': {
140
+ label: 'AI Fill-1',
141
+ desc: '轻量 AI 底色,适合输入框底色、聊天气泡背景、大面积铺底等弱感知场景',
142
+ css: 'linear-gradient(90deg, rgba(230, 247, 244, 1) 0%, rgba(239, 246, 255, 1) 55%, rgba(243, 245, 255, 1) 90%, rgba(252, 243, 255, 1) 100%)',
143
+ },
144
+ 'ai-fill-2': {
145
+ label: 'AI Fill-2',
146
+ desc: '中等 AI 底色,适合卡片悬浮态、推荐条 hover、弹层背景等次强调场景',
147
+ css: 'linear-gradient(-45deg, rgba(254, 224, 253, 1) 0%, rgba(233, 218, 255, 1) 25%, rgba(213, 225, 255, 1) 48%, rgba(213, 243, 248, 1) 83%, rgba(213, 247, 242, 1) 100%)',
148
+ },
149
+ 'ai-fill-3': {
150
+ label: 'AI Fill-3',
151
+ desc: '高饱和 AI 底色,适合激活态、强调态、封面视觉等强感知场景',
152
+ css: 'linear-gradient(-45deg, rgba(255, 153, 248, 1) 0%, rgba(181, 131, 255, 1) 25%, rgba(114, 156, 255, 1) 48%, rgba(117, 218, 231, 1) 83%, rgba(115, 230, 204, 1) 100%)',
153
+ },
154
+ 'ai-fill-text': {
155
+ label: 'AI Fill-text',
156
+ desc: 'AI 文字渐变,适合标题字、强调文案、AI 品牌标识文本',
157
+ css: 'linear-gradient(135deg, rgba(22, 218, 203, 1) 0%, rgba(49, 134, 212, 1) 20%, rgba(111, 88, 227, 1) 70%, rgba(231, 116, 221, 1) 100%)',
158
+ },
159
+ };
160
+
161
+ export const TOKEN_CUSTOM_BACKGROUNDS = {
162
+ 'chat-outgoing-ai': TOKEN_GRADIENTS['ai-fill-1'].css,
163
+ };
164
+
165
+ export const TOKEN_Z_INDEX = {
166
+ '0': 0, '10': 10, '20': 20, '30': 30, '40': 40, '50': 50,
167
+ };
168
+
169
+ export const TOKEN_BREAKPOINTS = {
170
+ sm: '640px', md: '768px', lg: '1024px', xl: '1280px', '2xl': '1536px',
171
+ };
172
+
173
+ export const TOKEN_MAX_WIDTH = {
174
+ xs: '20rem', sm: '24rem', md: '28rem', lg: '32rem', xl: '36rem',
175
+ '2xl': '42rem', '3xl': '48rem', '4xl': '56rem', '5xl': '64rem',
176
+ '6xl': '72rem', '7xl': '80rem',
177
+ };
178
+
179
+ // ── Semantic Mapping ────────────────────────────────────────
180
+ // 语义桥接层。MAP key 用于平台展示分组,CSS 变量名通过 SEMANTIC_CSS_MAP 映射到 --color-* 命名空间。
181
+ // Tailwind v4 @theme 只识别 --color-* 前缀,所以所有语义色统一输出为 --color-{name}。
182
+
183
+ export const SEMANTIC_CSS_MAP = {
184
+ 'status-primary': 'primary', 'status-success': 'success', 'status-warning': 'warning',
185
+ 'status-danger': 'danger', 'status-info': 'info', 'status-tertiary': 'tertiary',
186
+ 'text-link': 'link',
187
+ 'text-primary': 'foreground', 'text-secondary': 'foreground-secondary',
188
+ 'text-tertiary': 'foreground-muted', 'text-disabled': 'foreground-disabled', 'text-inverse': 'foreground-inverse',
189
+ 'bg-page': 'page', 'bg-surface': 'surface', 'bg-elevated': 'elevated', 'bg-disabled': 'disabled', 'bg-card-secondary': 'card-secondary', 'bg-chat-incoming': 'chat-incoming', 'bg-chat-outgoing': 'chat-outgoing', 'bg-chat-outgoing-ai': 'chat-outgoing-ai',
190
+ 'fill-default': 'fill', 'fill-hover': 'fill-hover', 'fill-active': 'fill-active',
191
+ 'border-default': 'border-default', 'border-strong': 'border-strong', 'border-brand': 'border-brand', 'border-brand-strong': 'border-brand-strong',
192
+ 'overlay-bg': 'overlay', 'focus-ring': 'ring',
193
+ };
194
+
195
+ export const TOKEN_SEMANTIC_MAP = {
196
+ // ── status: 状态 / 主题色 ──
197
+ 'status-primary': { label: 'Primary', color: '#56D3BC', primitiveRef: 'brand-500', states: { default: '{brand.500}', hover: '{brand.600}', active: '{brand.700}', bg: '{brand.50}' }},
198
+ 'status-success': { label: 'Success', color: '#3EB346', primitiveRef: 'green-500', states: { default: '{green.500}', hover: '{green.600}', active: '{green.700}', bg: '{green.50}' }},
199
+ 'status-warning': { label: 'Warning', color: '#FA8B14', primitiveRef: 'orange-500', states: { default: '{orange.500}', hover: '{orange.600}', active: '{orange.700}', bg: '{orange.50}' }},
200
+ 'status-danger': { label: 'Danger', color: '#F74331', primitiveRef: 'red-500', states: { default: '{red.500}', hover: '{red.600}', active: '{red.700}', bg: '{red.50}' }},
201
+ 'status-info': { label: 'Info', color: '#56D3BC', primitiveRef: 'brand-500', states: { default: '{brand.500}', hover: '{brand.600}', active: '{brand.700}', bg: '{brand.50}' }},
202
+ 'status-tertiary': { label: 'Tertiary', color: '#6B6C75', primitiveRef: 'grey-500', states: { default: '{grey.500}', hover: '{grey.600}', active: '{grey.700}', bg: '{grey.50}' }},
203
+ // ── text: 文字颜色 ──
204
+ 'text-primary': { label: '主文字', color: '#182230', primitiveRef: 'blueGrey-900' },
205
+ 'text-secondary': { label: '副文字', color: '#475467', primitiveRef: 'blueGrey-700' },
206
+ 'text-tertiary': { label: '辅助文字', color: '#667085', primitiveRef: 'blueGrey-600' },
207
+ 'text-disabled': { label: '禁用文字', color: '#98A2B3', primitiveRef: 'blueGrey-500' },
208
+ 'text-inverse': { label: '反色文字', color: '#FFFFFF', primitiveRef: 'white' },
209
+ 'text-link': { label: '链接文字', color: '#18B49D', primitiveRef: 'brand-700', states: { default: '{brand.700}', hover: '{brand.800}', active: '{brand.900}', bg: '{brand.50}' }},
210
+
211
+ // ── bg: 背景色 ──
212
+ 'bg-page': { label: '页面底层背景', color: '#FFFFFF', primitiveRef: 'white' },
213
+ 'bg-surface': { label: '容器 / 卡片背景', color: '#FFFFFF', primitiveRef: 'white' },
214
+ 'bg-elevated': { label: '浮层背景', color: '#FFFFFF', primitiveRef: 'white' },
215
+ 'bg-disabled': { label: '禁用背景', color: '#F9FAFB', primitiveRef: 'blueGrey-100' },
216
+ 'bg-card-secondary': { label: '卡片次级背景', color: 'rgba(255,255,255,0.65)', primitiveRef: 'white/65%' },
217
+ 'bg-chat-incoming': { label: '聊天气泡-左侧', color: 'rgba(52,59,57,0.05)', primitiveRef: 'grey-800/5%' },
218
+ 'bg-chat-outgoing': { label: '聊天气泡-右侧', color: '#E5F7F7', primitiveRef: 'cyan-soft/custom' },
219
+ 'bg-chat-outgoing-ai': { label: '聊天气泡-右侧AI渐变', color: TOKEN_CUSTOM_BACKGROUNDS['chat-outgoing-ai'], primitiveRef: 'gradient/ai-fill-1' },
220
+
221
+ // ── fill: 填充色 ──
222
+ 'fill-default': { label: '填充-默认态', color: 'rgba(83, 96, 143, 0.07)', primitiveRef: 'blueGrey/7%' },
223
+ 'fill-hover': { label: '填充-悬浮态', color: 'rgba(83, 96, 143, 0.12)', primitiveRef: 'blueGrey/12%' },
224
+ 'fill-active': { label: '填充-激活态', color: 'rgba(83, 96, 143, 0.15)', primitiveRef: 'blueGrey/15%' },
225
+
226
+ // ── border: 描边色 ──
227
+ 'border-default': { label: '默认描边', color: '#E4E7EC', primitiveRef: 'blueGrey-300' },
228
+ 'border-strong': { label: '强调/悬浮描边', color: '#D0D5DD', primitiveRef: 'blueGrey-400' },
229
+ 'border-brand': { label: '品牌描边', color: '#56D3BC', primitiveRef: 'brand-500' },
230
+ 'border-brand-strong': { label: '品牌强调描边', color: '#32C4AC', primitiveRef: 'brand-600' },
231
+ /** rgba 细线:ChatMessage 追问/执行流卡片描边;必须进 theme.css,否则 var() 失效时浏览器退化为深黑描边 */
232
+ 'border-line-light': { label: '细线描边 rgba', color: 'rgba(22,24,35,0.08)' },
233
+
234
+ // ── overlay: 蒙层 ──
235
+ 'overlay-bg': { label: '蒙层背景', color: 'rgba(22, 22, 26, 0.60)', primitiveRef: 'grey-950/60%' },
236
+
237
+ // ── focus: 焦点 ──
238
+ 'focus-ring': { label: '焦点环', color: '#56D3BC', primitiveRef: 'brand-500' },
239
+ };
240
+
241
+ // 兼容旧引用:从扁平 map 中按前缀提取分组视图
242
+ export const TOKEN_SEMANTIC = Object.fromEntries(
243
+ Object.entries(TOKEN_SEMANTIC_MAP)
244
+ .filter(([k]) => k.startsWith('status-'))
245
+ .map(([k, v]) => [k.replace('status-', ''), { ...v, default: v.states?.default, hover: v.states?.hover, active: v.states?.active, bg: v.states?.bg }])
246
+ );
247
+
248
+ export const TOKEN_TEXT_COLORS = Object.fromEntries(
249
+ Object.entries(TOKEN_SEMANTIC_MAP)
250
+ .filter(([k]) => k.startsWith('text-'))
251
+ .map(([k, v]) => [k.replace('text-', ''), { ...v, mapping: v.primitiveRef }])
252
+ );
253
+
254
+ export const TOKEN_FUNCTIONAL = Object.fromEntries(
255
+ Object.entries(TOKEN_SEMANTIC_MAP)
256
+ .filter(([k]) => !k.startsWith('status-') && !k.startsWith('text-'))
257
+ .map(([k, v]) => [k, { ...v, opacity: '—', varRef: v.primitiveRef }])
258
+ );
259
+
260
+ // ── Utility functions ───────────────────────────────────────
261
+
262
+ function primitiveRefToCssVar(ref) {
263
+ if (!ref) return undefined;
264
+ if (ref === 'black') return 'var(--color-black)';
265
+ if (ref === 'white') return 'var(--color-white)';
266
+ if (ref.includes('/')) return undefined;
267
+ return `var(--color-${ref})`;
268
+ }
269
+
270
+ export function generateThemeCssVars() {
271
+ const lines = ['@theme {'];
272
+
273
+ lines.push(' /* ── Colors ── */');
274
+ lines.push(' --color-black: #000000;');
275
+ lines.push(' --color-transparent: transparent;');
276
+ lines.push(' --color-white: #FFFFFF;');
277
+ Object.entries(TOKEN_COLORS).forEach(([name, { shades }]) => {
278
+ Object.entries(shades).forEach(([shade, hex]) => {
279
+ lines.push(` --color-${name}-${shade}: ${hex};`);
280
+ });
281
+ });
282
+
283
+ lines.push('');
284
+ lines.push(' /* ── Component-only colors(组件特化色,命名空间共用 --color-*,不进通用调色板)── */');
285
+ Object.entries(TOKEN_COMPONENT_COLORS).forEach(([name, { shades, usedBy }]) => {
286
+ const usedByStr = Array.isArray(usedBy) ? usedBy.join(', ') : usedBy;
287
+ Object.entries(shades).forEach(([shade, hex]) => {
288
+ lines.push(` --color-${name}-${shade}: ${hex}; /* used by: ${usedByStr} */`);
289
+ });
290
+ });
291
+
292
+ lines.push('');
293
+ lines.push(' /* ── Semantic tokens → --color-* 命名空间 ── */');
294
+ Object.entries(TOKEN_SEMANTIC_MAP).forEach(([key, tok]) => {
295
+ const cssName = SEMANTIC_CSS_MAP[key] || key;
296
+ const cssVal = primitiveRefToCssVar(tok.primitiveRef) || tok.color;
297
+ const refNote = tok.primitiveRef != null ? tok.primitiveRef : 'literal';
298
+ lines.push(` --color-${cssName}: ${cssVal}; /* ${tok.label} ← ${refNote} */`);
299
+ });
300
+
301
+ lines.push('');
302
+ lines.push(' /* ── 兼容别名:Tailwind v4 默认 border 工具读取 --color-border ── */');
303
+ lines.push(' --color-border: var(--color-border-default);');
304
+
305
+ lines.push('');
306
+ lines.push(' /* ── Custom backgrounds ── */');
307
+ Object.entries(TOKEN_CUSTOM_BACKGROUNDS).forEach(([key, value]) => {
308
+ lines.push(` --bg-${key}: ${value};`);
309
+ });
310
+
311
+ lines.push('');
312
+ lines.push(' /* ── Data colors(图表色,硬编码 hex)── */');
313
+ TOKEN_DATA_COLORS.forEach((hex, i) => {
314
+ lines.push(` --color-data-${i}: ${hex};`);
315
+ });
316
+
317
+ lines.push('');
318
+ lines.push(' /* ── Spacing ── */');
319
+ Object.entries(TOKEN_SPACING).forEach(([k, v]) => {
320
+ lines.push(` --spacing-${k}: ${v};`);
321
+ });
322
+
323
+ lines.push('');
324
+ lines.push(' /* ── Font Family(英文 Inter + 中文苹方)── */');
325
+ lines.push(` --font-sans: ${TOKEN_FONT_STACK};`);
326
+
327
+ lines.push('');
328
+ lines.push(' /* ── Font Size ── */');
329
+ Object.entries(TOKEN_FONT_SIZE).forEach(([k, v]) => {
330
+ lines.push(` --text-${k}: ${v}; /* ${TOKEN_FONT_SIZE_PX[k]}px */`);
331
+ });
332
+
333
+ lines.push('');
334
+ lines.push(' /* ── Font Weight ── */');
335
+ Object.entries(TOKEN_FONT_WEIGHT).forEach(([k, v]) => {
336
+ lines.push(` --font-${k}: ${v};`);
337
+ });
338
+
339
+ lines.push('');
340
+ lines.push(' /* ── Line Height ── */');
341
+ Object.entries(TOKEN_LINE_HEIGHT).forEach(([k, v]) => {
342
+ lines.push(` --leading-${k}: ${v};`);
343
+ });
344
+
345
+ lines.push('');
346
+ lines.push(' /* ── Letter Spacing ── */');
347
+ Object.entries(TOKEN_LETTER_SPACING).forEach(([k, v]) => {
348
+ lines.push(` --tracking-${k}: ${v};`);
349
+ });
350
+
351
+ lines.push('');
352
+ lines.push(' /* ── Border Radius ── */');
353
+ Object.entries(TOKEN_RADIUS).forEach(([k, v]) => {
354
+ lines.push(` --radius-${k}: ${v};`);
355
+ });
356
+
357
+ lines.push('');
358
+ lines.push(' /* ── Size ── */');
359
+ Object.entries(TOKEN_SIZE).forEach(([k, v]) => {
360
+ lines.push(` --size-${k}: ${v};`);
361
+ });
362
+
363
+ lines.push('');
364
+ lines.push(' /* ── Shadows ── */');
365
+ Object.entries(TOKEN_SHADOWS).forEach(([k, v]) => {
366
+ lines.push(` --shadow-${k}: ${v};`);
367
+ });
368
+
369
+ lines.push('');
370
+ lines.push(' /* ── Gradients ── */');
371
+ Object.entries(TOKEN_GRADIENTS).forEach(([k, g]) => {
372
+ lines.push(` --gradient-${k}: ${g.css};`);
373
+ });
374
+
375
+ lines.push('}');
376
+
377
+ /* ChatMessage / 执行流:组件内 var(--tfds-ai-execution-*) 与 Tailwind 任意动画名依赖 */
378
+ lines.push('');
379
+ lines.push('/* ── ChatMessage 执行流:全局变量与动画(与平台 src/index.css 对齐,随 theme.css 一并下发)── */');
380
+ lines.push(':root {');
381
+ lines.push(' --tfds-ai-execution-icon-gradient: linear-gradient(180deg, rgba(200, 214, 210, 0.09) 0%, rgba(52, 59, 57, 0.09) 100%);');
382
+ lines.push(' --tfds-ai-execution-processing-fill: rgba(52, 59, 57, 0.04);');
383
+ lines.push(' --tfds-ai-execution-processing-shimmer: linear-gradient(90deg, rgba(52, 59, 57, 0.045) 0%, rgba(52, 59, 57, 0.05) 28%, rgba(255, 255, 255, 0.18) 50%, rgba(52, 59, 57, 0.05) 72%, rgba(52, 59, 57, 0.045) 100%);');
384
+ lines.push('}');
385
+ lines.push('@keyframes tfds-ai-execution-shimmer {');
386
+ lines.push(' 0% { background-position: 140% 0; }');
387
+ lines.push(' 100% { background-position: -40% 0; }');
388
+ lines.push('}');
389
+
390
+ return lines.join('\n');
391
+ }
392
+
393
+ export function generateCSSVarsForCategory(category) {
394
+ const lines = [];
395
+ switch (category) {
396
+ case 'colors':
397
+ lines.push('--color-black: #000000;');
398
+ lines.push('--color-white: #FFFFFF;');
399
+ Object.entries(TOKEN_COLORS).forEach(([name, { shades }]) => {
400
+ Object.entries(shades).forEach(([shade, hex]) => {
401
+ lines.push(`--color-${name}-${shade}: ${hex};`);
402
+ });
403
+ });
404
+ break;
405
+ case 'componentColors':
406
+ Object.entries(TOKEN_COMPONENT_COLORS).forEach(([name, { shades, usedBy }]) => {
407
+ const usedByStr = Array.isArray(usedBy) ? usedBy.join(', ') : usedBy;
408
+ Object.entries(shades).forEach(([shade, hex]) => {
409
+ lines.push(`--color-${name}-${shade}: ${hex}; /* used by: ${usedByStr} */`);
410
+ });
411
+ });
412
+ break;
413
+ case 'semantic':
414
+ Object.entries(TOKEN_SEMANTIC_MAP).forEach(([key, tok]) => {
415
+ const cssName = SEMANTIC_CSS_MAP[key] || key;
416
+ const cssVal = primitiveRefToCssVar(tok.primitiveRef) || tok.color;
417
+ const refNote = tok.primitiveRef != null ? tok.primitiveRef : 'literal';
418
+ lines.push(`--color-${cssName}: ${cssVal}; /* ${tok.label} ← ${refNote} */`);
419
+ });
420
+ Object.entries(TOKEN_CUSTOM_BACKGROUNDS).forEach(([key, value]) => {
421
+ lines.push(`--bg-${key}: ${value};`);
422
+ });
423
+ break;
424
+ case 'dataColors':
425
+ TOKEN_DATA_COLORS.forEach((hex, i) => {
426
+ lines.push(`--color-data-${i}: ${hex};`);
427
+ });
428
+ break;
429
+ case 'spacing':
430
+ Object.entries(TOKEN_SPACING).forEach(([k, v]) => {
431
+ lines.push(`--spacing-${k}: ${v};`);
432
+ });
433
+ break;
434
+ case 'typography':
435
+ lines.push('/* 字体栈 */');
436
+ lines.push(`--font-sans: ${TOKEN_FONT_STACK};`);
437
+ lines.push('');
438
+ lines.push('/* 字重 */');
439
+ Object.entries(TOKEN_FONT_WEIGHT).forEach(([k, v]) => {
440
+ lines.push(`--font-${k}: ${v};`);
441
+ });
442
+ lines.push('');
443
+ lines.push('/* 字号 */');
444
+ Object.entries(TOKEN_FONT_SIZE).forEach(([k, v]) => {
445
+ lines.push(`--text-${k}: ${v}; /* ${TOKEN_FONT_SIZE_PX[k]}px */`);
446
+ });
447
+ lines.push('');
448
+ lines.push('/* 行高 */');
449
+ Object.entries(TOKEN_LINE_HEIGHT).forEach(([k, v]) => {
450
+ lines.push(`--leading-${k}: ${v};`);
451
+ });
452
+ break;
453
+ case 'radius':
454
+ Object.entries(TOKEN_RADIUS).forEach(([k, v]) => {
455
+ lines.push(`--radius-${k}: ${v};`);
456
+ });
457
+ break;
458
+ case 'shadows':
459
+ Object.entries(TOKEN_SHADOWS).forEach(([k, v]) => {
460
+ lines.push(`--shadow-${k}: ${v};`);
461
+ });
462
+ break;
463
+ case 'size':
464
+ Object.entries(TOKEN_SIZE).forEach(([k, v]) => {
465
+ lines.push(`--size-${k}: ${v};`);
466
+ });
467
+ break;
468
+ case 'gradients':
469
+ Object.entries(TOKEN_GRADIENTS).forEach(([k, g]) => {
470
+ lines.push(`--gradient-${k}: ${g.css};`);
471
+ });
472
+ break;
473
+ default:
474
+ break;
475
+ }
476
+ return lines.join('\n');
477
+ }
478
+
479
+ export function countTokens() {
480
+ let count = 0;
481
+ Object.values(TOKEN_COLORS).forEach(c => { count += Object.keys(c.shades).length; });
482
+ Object.values(TOKEN_COMPONENT_COLORS).forEach(c => { count += Object.keys(c.shades).length; });
483
+ count += Object.keys(TOKEN_SPACING).length;
484
+ count += Object.keys(TOKEN_RADIUS).length;
485
+ count += Object.keys(TOKEN_FONT_SIZE).length;
486
+ count += Object.keys(TOKEN_FONT_WEIGHT).length;
487
+ count += Object.keys(TOKEN_LINE_HEIGHT).length;
488
+ count += Object.keys(TOKEN_SIZE).length;
489
+ count += 1; // font-family
490
+ count += Object.keys(TOKEN_LETTER_SPACING).length;
491
+ count += Object.keys(TOKEN_SHADOWS).length;
492
+ count += Object.keys(TOKEN_GRADIENTS).length;
493
+ count += Object.keys(TOKEN_Z_INDEX).length;
494
+ count += Object.keys(TOKEN_BREAKPOINTS).length;
495
+ count += Object.keys(TOKEN_MAX_WIDTH).length;
496
+ count += TOKEN_DATA_COLORS.length;
497
+ count += Object.keys(TOKEN_SEMANTIC_MAP).length;
498
+ count += Object.keys(TOKEN_CUSTOM_BACKGROUNDS).length;
499
+ return count;
500
+ }