@deernova/style 0.2.0 → 0.3.1

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 (133) hide show
  1. package/README.md +19 -9
  2. package/bin/cli.mjs +212 -32
  3. package/package.json +1 -1
  4. package/skill/SKILL.md +90 -22
  5. package/skill/assets/DeernovaTokens.swift +376 -0
  6. package/skill/assets/screens/iphone-button-sizes-dark.png +0 -0
  7. package/skill/assets/screens/iphone-button-sizes-light.png +0 -0
  8. package/skill/assets/screens/iphone-screens-dark.png +0 -0
  9. package/skill/assets/screens/iphone-screens-light.png +0 -0
  10. package/skill/assets/screens/mac-window-dark.png +0 -0
  11. package/skill/assets/screens/mac-window-light.png +0 -0
  12. package/skill/assets/tailwind.css +106 -0
  13. package/skill/assets/tokens.css +533 -0
  14. package/skill/assets/tokens.json +1686 -0
  15. package/skill/manifest.json +2 -22
  16. package/skill/references/components/banner.md +95 -0
  17. package/skill/references/components/button.md +181 -0
  18. package/skill/references/components/card.md +89 -0
  19. package/skill/references/components/code-block.md +77 -0
  20. package/skill/references/components/composer.md +206 -0
  21. package/skill/references/components/empty-state.md +63 -0
  22. package/skill/references/components/glass-controls.md +127 -0
  23. package/skill/references/components/list.md +130 -0
  24. package/skill/references/components/message.md +94 -0
  25. package/skill/references/components/segmented.md +79 -0
  26. package/skill/references/components/sheet.md +84 -0
  27. package/skill/references/components/sidebar.md +139 -0
  28. package/skill/references/components/step-row.md +135 -0
  29. package/skill/references/components/tag.md +86 -0
  30. package/skill/references/components/task-list.md +83 -0
  31. package/skill/references/components/text-field.md +86 -0
  32. package/skill/references/components/toolbar.md +139 -0
  33. package/skill/references/foundations/accessibility.md +27 -0
  34. package/skill/references/foundations/color.md +58 -0
  35. package/skill/references/foundations/elevation.md +17 -0
  36. package/skill/references/foundations/glass.md +36 -0
  37. package/skill/references/foundations/iconography.md +44 -0
  38. package/skill/references/foundations/motion.md +22 -0
  39. package/skill/references/foundations/radius.md +31 -0
  40. package/skill/references/foundations/spacing.md +38 -0
  41. package/skill/references/foundations/stroke.md +35 -0
  42. package/skill/references/foundations/typography.md +54 -0
  43. package/skill/references/foundations/writing.md +10 -0
  44. package/skill/references/review.md +26 -13
  45. package/skill/references/scenes/ios.md +61 -0
  46. package/skill/references/scenes/ipados.md +42 -0
  47. package/skill/references/scenes/macos.md +65 -0
  48. package/skill/references/scenes/swiftui.md +94 -0
  49. package/skill/references/scenes/web-marketing.md +34 -0
  50. package/skill/references/scenes/web.md +83 -0
  51. package/skill/references/tokens.md +441 -74
  52. package/skill/assets/design/README.md +0 -170
  53. package/skill/assets/design/components/Banner/README.md +0 -33
  54. package/skill/assets/design/components/Banner/preview.html +0 -26
  55. package/skill/assets/design/components/Button/README.md +0 -59
  56. package/skill/assets/design/components/Button/preview.html +0 -27
  57. package/skill/assets/design/components/Card/README.md +0 -31
  58. package/skill/assets/design/components/Card/preview.html +0 -24
  59. package/skill/assets/design/components/CodeBlock/README.md +0 -34
  60. package/skill/assets/design/components/CodeBlock/preview.html +0 -16
  61. package/skill/assets/design/components/Composer/README.md +0 -42
  62. package/skill/assets/design/components/Composer/preview.html +0 -28
  63. package/skill/assets/design/components/Cover/preview.html +0 -53
  64. package/skill/assets/design/components/EmptyState/README.md +0 -28
  65. package/skill/assets/design/components/EmptyState/preview.html +0 -16
  66. package/skill/assets/design/components/GlassControls/README.md +0 -43
  67. package/skill/assets/design/components/GlassControls/preview.html +0 -40
  68. package/skill/assets/design/components/ListGroup/README.md +0 -39
  69. package/skill/assets/design/components/ListGroup/preview.html +0 -22
  70. package/skill/assets/design/components/MacWindow/README.md +0 -27
  71. package/skill/assets/design/components/MacWindow/preview.html +0 -70
  72. package/skill/assets/design/components/Message/README.md +0 -31
  73. package/skill/assets/design/components/Message/preview.html +0 -21
  74. package/skill/assets/design/components/PhoneScreen/README.md +0 -25
  75. package/skill/assets/design/components/PhoneScreen/preview.html +0 -74
  76. package/skill/assets/design/components/Segmented/README.md +0 -21
  77. package/skill/assets/design/components/Segmented/preview.html +0 -21
  78. package/skill/assets/design/components/Sheet/README.md +0 -29
  79. package/skill/assets/design/components/Sheet/preview.html +0 -31
  80. package/skill/assets/design/components/Sidebar/README.md +0 -36
  81. package/skill/assets/design/components/Sidebar/preview.html +0 -20
  82. package/skill/assets/design/components/StepRow/README.md +0 -35
  83. package/skill/assets/design/components/StepRow/preview.html +0 -17
  84. package/skill/assets/design/components/Tag/README.md +0 -36
  85. package/skill/assets/design/components/Tag/preview.html +0 -22
  86. package/skill/assets/design/components/TextField/README.md +0 -29
  87. package/skill/assets/design/components/TextField/preview.html +0 -28
  88. package/skill/assets/design/components/bundle.css +0 -189
  89. package/skill/assets/design/design-system.json +0 -25
  90. package/skill/assets/design/images/Banner-dark.png +0 -0
  91. package/skill/assets/design/images/Banner-light.png +0 -0
  92. package/skill/assets/design/images/Button-dark.png +0 -0
  93. package/skill/assets/design/images/Button-light.png +0 -0
  94. package/skill/assets/design/images/Card-dark.png +0 -0
  95. package/skill/assets/design/images/Card-light.png +0 -0
  96. package/skill/assets/design/images/CodeBlock-dark.png +0 -0
  97. package/skill/assets/design/images/CodeBlock-light.png +0 -0
  98. package/skill/assets/design/images/Composer-dark.png +0 -0
  99. package/skill/assets/design/images/Composer-light.png +0 -0
  100. package/skill/assets/design/images/Cover-dark.png +0 -0
  101. package/skill/assets/design/images/Cover-light.png +0 -0
  102. package/skill/assets/design/images/EmptyState-dark.png +0 -0
  103. package/skill/assets/design/images/EmptyState-light.png +0 -0
  104. package/skill/assets/design/images/Example-iOSButtonsInPhone-dark.png +0 -0
  105. package/skill/assets/design/images/Example-iOSButtonsInPhone-light.png +0 -0
  106. package/skill/assets/design/images/GlassControls-dark.png +0 -0
  107. package/skill/assets/design/images/GlassControls-light.png +0 -0
  108. package/skill/assets/design/images/ListGroup-dark.png +0 -0
  109. package/skill/assets/design/images/ListGroup-light.png +0 -0
  110. package/skill/assets/design/images/MacWindow-dark.png +0 -0
  111. package/skill/assets/design/images/MacWindow-light.png +0 -0
  112. package/skill/assets/design/images/Message-dark.png +0 -0
  113. package/skill/assets/design/images/Message-light.png +0 -0
  114. package/skill/assets/design/images/PhoneScreen-dark.png +0 -0
  115. package/skill/assets/design/images/PhoneScreen-light.png +0 -0
  116. package/skill/assets/design/images/Segmented-dark.png +0 -0
  117. package/skill/assets/design/images/Segmented-light.png +0 -0
  118. package/skill/assets/design/images/Sheet-dark.png +0 -0
  119. package/skill/assets/design/images/Sheet-light.png +0 -0
  120. package/skill/assets/design/images/Sidebar-dark.png +0 -0
  121. package/skill/assets/design/images/Sidebar-light.png +0 -0
  122. package/skill/assets/design/images/StepRow-dark.png +0 -0
  123. package/skill/assets/design/images/StepRow-light.png +0 -0
  124. package/skill/assets/design/images/Tag-dark.png +0 -0
  125. package/skill/assets/design/images/Tag-light.png +0 -0
  126. package/skill/assets/design/images/TextField-dark.png +0 -0
  127. package/skill/assets/design/images/TextField-light.png +0 -0
  128. package/skill/assets/design/tokens.css +0 -187
  129. package/skill/assets/design/tokens.json +0 -142
  130. package/skill/references/components.md +0 -648
  131. package/skill/references/foundations.md +0 -170
  132. package/skill/references/native.md +0 -7
  133. package/skill/references/web.md +0 -11
@@ -0,0 +1,376 @@
1
+ // Generated from tokens.json by `npm run tokens`. Do not edit by hand.
2
+ //
3
+ // Deernova 的 SwiftUI 设计变量。把这个文件加进 App target 即可使用,不需要 Asset Catalog。
4
+ // 颜色跟随浅色 / 深色外观;尺寸在 macOS 上是 desktop 密度,在 iOS 和 iPadOS 上是 touch 密度。
5
+ // macOS 的侧边栏、工具栏、菜单用系统控件和系统尺寸;这里的尺寸用于自己画的内容区。
6
+
7
+ import SwiftUI
8
+ #if canImport(UIKit)
9
+ import UIKit
10
+ #elseif canImport(AppKit)
11
+ import AppKit
12
+ #endif
13
+
14
+ extension Color {
15
+ fileprivate init(deernovaLight light: UInt32, _ lightAlpha: Double, dark: UInt32, _ darkAlpha: Double) {
16
+ func components(_ hex: UInt32) -> (Double, Double, Double) {
17
+ (Double((hex >> 16) & 0xFF) / 255, Double((hex >> 8) & 0xFF) / 255, Double(hex & 0xFF) / 255)
18
+ }
19
+ #if canImport(UIKit)
20
+ self.init(uiColor: UIColor { traits in
21
+ let (hex, alpha) = traits.userInterfaceStyle == .dark ? (dark, darkAlpha) : (light, lightAlpha)
22
+ let (r, g, b) = components(hex)
23
+ return UIColor(red: r, green: g, blue: b, alpha: alpha)
24
+ })
25
+ #elseif canImport(AppKit)
26
+ self.init(nsColor: NSColor(name: nil) { appearance in
27
+ let isDark = appearance.bestMatch(from: [.aqua, .darkAqua]) == .darkAqua
28
+ let (hex, alpha) = isDark ? (dark, darkAlpha) : (light, lightAlpha)
29
+ let (r, g, b) = components(hex)
30
+ return NSColor(srgbRed: r, green: g, blue: b, alpha: alpha)
31
+ })
32
+ #endif
33
+ }
34
+ }
35
+
36
+ /// 语义颜色。accent 命名为 brandAccent,避开系统的 accentColor。
37
+ public enum DeernovaColor {
38
+ /// 窗口底色、Web 应用的内容区、分组列表的底色。最底层的纸面。
39
+ public static let canvas = Color(deernovaLight: 0xF5F5F5, 1, dark: 0x171717, 1)
40
+ /// 卡片、侧边栏(比内容区亮一层)。
41
+ public static let surface = Color(deernovaLight: 0xFAFAFA, 1, dark: 0x1C1C1C, 1)
42
+ /// 输入框、Composer、用户消息气泡、分组列表、弹出层。最亮的纸面。
43
+ public static let surfaceRaised = Color(deernovaLight: 0xFFFFFF, 1, dark: 0x252525, 1)
44
+ /// 代码块、展开的步骤详情。凹下去的纸面。
45
+ public static let surfaceSunken = Color(deernovaLight: 0xEBEBEB, 1, dark: 0x111111, 1)
46
+ /// 正文与标题,在四种纸面上不低于 13:1。
47
+ public static let ink = Color(deernovaLight: 0x171717, 1, dark: 0xEDEDED, 1)
48
+ /// 次要文字、说明、列表的值、未选中的图标,在四种纸面上不低于 6:1。
49
+ public static let inkSecondary = Color(deernovaLight: 0x525252, 1, dark: 0xA3A3A3, 1)
50
+ /// 占位符、时间戳、计数、分组标题,在四种纸面上不低于 4.5:1。
51
+ public static let inkTertiary = Color(deernovaLight: 0x666666, 1, dark: 0x8C8C8C, 1)
52
+ /// 分隔线、卡片描边、按钮描边。装饰性,不承载信息。
53
+ public static let line = Color(deernovaLight: 0xE3E3E3, 1, dark: 0x2F2F2F, 1)
54
+ /// 输入框边框、拖拽条、链接下划线。在 canvas、surface、surface-raised 上不低于 3:1。
55
+ public static let lineControl = Color(deernovaLight: 0x8A8A8A, 1, dark: 0x737373, 1)
56
+ public static let brandAccent = ink
57
+ /// 强调的浅底:列表图标底、输入框聚焦光晕。上面的文字用 ink。
58
+ public static let accentSoft = Color(deernovaLight: 0xE8E8E8, 1, dark: 0x2F2F2F, 1)
59
+ /// accent 填充上的文字和图标:浅色主题白字,深色主题黑字。
60
+ public static let onAccent = Color(deernovaLight: 0xFFFFFF, 1, dark: 0x171717, 1)
61
+ public static let focusRing = brandAccent
62
+ /// 成功、已完成、已同步、开关打开。作为文字用在纸面和 success-soft 上。
63
+ public static let success = Color(deernovaLight: 0x1F6B66, 1, dark: 0x6CC3B4, 1)
64
+ /// 成功状态的浅底(标签、横幅)。
65
+ public static let successSoft = Color(deernovaLight: 0xDDEEEC, 1, dark: 0x183230, 1)
66
+ /// 需要注意但不阻断:额度将用完、网络较慢。
67
+ public static let warning = Color(deernovaLight: 0x8A5A0B, 1, dark: 0xE2B054, 1)
68
+ /// 警告状态的浅底。
69
+ public static let warningSoft = Color(deernovaLight: 0xF5EAD3, 1, dark: 0x3A2E17, 1)
70
+ /// 错误、失败、删除。永远同时配图标或文字。
71
+ public static let danger = Color(deernovaLight: 0xB0283F, 1, dark: 0xF07A8A, 1)
72
+ /// 错误状态的浅底、危险按钮的底色。
73
+ public static let dangerSoft = Color(deernovaLight: 0xF7E1E4, 1, dark: 0x3D2027, 1)
74
+ /// 中性提示。
75
+ public static let info = Color(deernovaLight: 0x2C5F86, 1, dark: 0x82B4DC, 1)
76
+ /// 提示状态的浅底。
77
+ public static let infoSoft = Color(deernovaLight: 0xE1EBF3, 1, dark: 0x1D2C3A, 1)
78
+ /// 悬停底色,叠在任何纸面上(列表行、文字按钮、侧边栏项)。
79
+ public static let fillHover = Color(deernovaLight: 0x000000, 0.039, dark: 0xFFFFFF, 0.059)
80
+ /// 选中底色:侧边栏当前项、分段控件底槽、次按钮、中性标签底。比悬停明显,一眼能看出当前在哪。
81
+ public static let fillSelected = Color(deernovaLight: 0x000000, 0.09, dark: 0xFFFFFF, 0.149)
82
+ /// 开关的圆钮,两套主题都是白色,与系统一致。
83
+ public static let knob = Color(deernovaLight: 0xFFFFFF, 1, dark: 0xFFFFFF, 1)
84
+ /// 弹窗背后压暗内容的遮罩。
85
+ public static let scrim = Color(deernovaLight: 0x000000, 0.322, dark: 0x000000, 0.502)
86
+ }
87
+
88
+ /// 让 .foregroundStyle(.inkSecondary)、.background(.surface, in: …) 直接可用。
89
+ public extension ShapeStyle where Self == Color {
90
+ static var canvas: Color { DeernovaColor.canvas }
91
+ static var surface: Color { DeernovaColor.surface }
92
+ static var surfaceRaised: Color { DeernovaColor.surfaceRaised }
93
+ static var surfaceSunken: Color { DeernovaColor.surfaceSunken }
94
+ static var ink: Color { DeernovaColor.ink }
95
+ static var inkSecondary: Color { DeernovaColor.inkSecondary }
96
+ static var inkTertiary: Color { DeernovaColor.inkTertiary }
97
+ static var line: Color { DeernovaColor.line }
98
+ static var lineControl: Color { DeernovaColor.lineControl }
99
+ static var brandAccent: Color { DeernovaColor.brandAccent }
100
+ static var accentSoft: Color { DeernovaColor.accentSoft }
101
+ static var onAccent: Color { DeernovaColor.onAccent }
102
+ static var focusRing: Color { DeernovaColor.focusRing }
103
+ static var success: Color { DeernovaColor.success }
104
+ static var successSoft: Color { DeernovaColor.successSoft }
105
+ static var warning: Color { DeernovaColor.warning }
106
+ static var warningSoft: Color { DeernovaColor.warningSoft }
107
+ static var danger: Color { DeernovaColor.danger }
108
+ static var dangerSoft: Color { DeernovaColor.dangerSoft }
109
+ static var info: Color { DeernovaColor.info }
110
+ static var infoSoft: Color { DeernovaColor.infoSoft }
111
+ static var fillHover: Color { DeernovaColor.fillHover }
112
+ static var fillSelected: Color { DeernovaColor.fillSelected }
113
+ static var knob: Color { DeernovaColor.knob }
114
+ static var scrim: Color { DeernovaColor.scrim }
115
+ }
116
+
117
+ /// 尺寸、间距、圆角、时长。
118
+ public enum Deernova {
119
+ /// 图标与文字之间、标题与摘要之间。
120
+ public static let space1: CGFloat = 4
121
+ /// 列表项内边距、横幅上下内边距、卡片网格间距。
122
+ public static let space2: CGFloat = 8
123
+ /// 卡片内边距、横幅左右内边距。
124
+ public static let space3: CGFloat = 12
125
+ /// 内容区里段落、工具调用行、卡片之间。
126
+ public static let space4: CGFloat = 16
127
+ /// 分组之间、区块之间。
128
+ public static let space5: CGFloat = 20
129
+ /// 空状态内边距、大区块之间。
130
+ public static let space6: CGFloat = 24
131
+ /// 页面级留白。
132
+ public static let space8: CGFloat = 32
133
+ /// 引导页、首屏的留白。
134
+ public static let space10: CGFloat = 40
135
+ /// 官网与文档的章节间距。
136
+ public static let space12: CGFloat = 48
137
+ /// 官网首屏的上下留白。
138
+ public static let space16: CGFloat = 64
139
+ /// 标签、复选框、小按钮。
140
+ public static let radiusXs: CGFloat = 4
141
+ /// 桌面端的按钮、输入框、工具栏图标按钮。
142
+ public static let radiusSm: CGFloat = 6
143
+ /// 侧边栏选中块、代码块、弹出菜单。
144
+ public static let radiusMd: CGFloat = 8
145
+ /// 卡片、用户消息气泡、分组列表、任务清单。
146
+ public static let radiusLg: CGFloat = 12
147
+ /// 底部弹窗、触控端单行 Composer。
148
+ public static let radiusXl: CGFloat = 24
149
+ /// 胶囊与圆形:触控端按钮、玻璃按钮、状态圆点。
150
+ public static let radiusFull: CGFloat = 999
151
+ /// 分隔线、卡片、输入区、侧边栏和顶栏的边线。SwiftUI 里自己画的边框用 1pt,系统自带的分隔线保持系统样式。
152
+ public static let strokeLine: CGFloat = 1
153
+ /// 输入框边框、选中卡片的描边(配 line-control 或 ink 色)。
154
+ public static let strokeControl: CGFloat = 1
155
+ /// 键盘焦点环。
156
+ public static let strokeFocus: CGFloat = 2
157
+ /// 焦点环和控件边缘之间的距离。
158
+ public static let focusOffset: CGFloat = 2
159
+ /// 悬停、按压、选中这类即时反馈。
160
+ public static let durationInstant: Double = 0.12
161
+ /// 展开、收起、切换、开关。
162
+ public static let durationBase: Double = 0.2
163
+ /// 面板滑入、页面级转场。
164
+ public static let durationSlow: Double = 0.32
165
+ /// 禁用的控件。禁用时保持原位,不隐藏。
166
+ public static let opacityDisabled: Double = 0.35
167
+ /// 实色(accent 填充)按钮悬停和按下。
168
+ public static let opacitySolidHover: Double = 0.88
169
+ /// 对话栏和长文阅读栏的最大宽度。
170
+ public static let contentMax: CGFloat = 680
171
+
172
+ // 按密度取值的尺寸:macOS 是 desktop(只用于自己画的内容区),iOS 和 iPadOS 是 touch。
173
+ #if os(macOS)
174
+ public static let gapInline: CGFloat = 6
175
+ public static let gapStack: CGFloat = 8
176
+ public static let gapGroup: CGFloat = 24
177
+ public static let pageMargin: CGFloat = 32
178
+ public static let hitMin: CGFloat = 24
179
+ public static let sidebarWidth: CGFloat = 288
180
+ public static let toolbarHeight: CGFloat = 44
181
+ public static let buttonHeightSm: CGFloat = 24
182
+ public static let buttonHeightMd: CGFloat = 28
183
+ public static let buttonHeightLg: CGFloat = 32
184
+ public static let buttonPaddingXSm: CGFloat = 8
185
+ public static let buttonPaddingXMd: CGFloat = 12
186
+ public static let buttonPaddingXLg: CGFloat = 16
187
+ public static let buttonFontSizeSm: CGFloat = 12
188
+ public static let buttonFontSizeMd: CGFloat = 14
189
+ public static let buttonFontSizeLg: CGFloat = 14
190
+ public static let buttonFontWeight: Int = 500
191
+ public static let buttonRadius: CGFloat = 6
192
+ public static let buttonRadiusSm: CGFloat = 4
193
+ public static let toolbarTitleSize: CGFloat = 15
194
+ public static let panelTabHeight: CGFloat = 28
195
+ public static let glassButtonSize: CGFloat = 34
196
+ public static let segmentedHeight: CGFloat = 24
197
+ public static let segmentedPadding: CGFloat = 2
198
+ public static let segmentedPaddingX: CGFloat = 12
199
+ public static let segmentedFontSize: CGFloat = 13
200
+ public static let segmentedRadius: CGFloat = 6
201
+ public static let fieldHeight: CGFloat = 28
202
+ public static let fieldPaddingX: CGFloat = 10
203
+ public static let fieldFontSize: CGFloat = 14
204
+ public static let fieldRadius: CGFloat = 6
205
+ public static let composerRadius: CGFloat = 14
206
+ public static let composerMinHeight: CGFloat = 44
207
+ public static let rowHeight: CGFloat = 32
208
+ public static let rowPaddingX: CGFloat = 10
209
+ public static let rowRadius: CGFloat = 8
210
+ public static let rowGap: CGFloat = 2
211
+ public static let rowIconSize: CGFloat = 20
212
+ public static let switchWidth: CGFloat = 36
213
+ public static let switchHeight: CGFloat = 20
214
+ public static let cardPaddingX: CGFloat = 16
215
+ public static let cardPaddingY: CGFloat = 12
216
+ public static let cardRadius: CGFloat = 12
217
+ public static let cardGap: CGFloat = 12
218
+ public static let tagHeight: CGFloat = 20
219
+ public static let tagPaddingX: CGFloat = 6
220
+ public static let tagFontSize: CGFloat = 12
221
+ public static let tagRadius: CGFloat = 4
222
+ public static let codeHeaderHeight: CGFloat = 32
223
+ public static let taskRowHeight: CGFloat = 28
224
+ public static let taskGlyphSize: CGFloat = 16
225
+ public static let emptyTitleSize: CGFloat = 24
226
+ public static let emptyIconSize: CGFloat = 32
227
+ public static let toastHeight: CGFloat = 36
228
+ public static let bannerRadius: CGFloat = 10
229
+ public static let sheetRadius: CGFloat = 12
230
+ public static let menuRadius: CGFloat = 8
231
+ public static let messageFontSize: CGFloat = 15
232
+ public static let messageActionSize: CGFloat = 24
233
+ public static let iconSizeSm: CGFloat = 14
234
+ public static let iconSizeMd: CGFloat = 16
235
+ public static let iconSizeLg: CGFloat = 20
236
+ #else
237
+ public static let gapInline: CGFloat = 6
238
+ public static let gapStack: CGFloat = 8
239
+ public static let gapGroup: CGFloat = 20
240
+ public static let pageMargin: CGFloat = 16
241
+ public static let hitMin: CGFloat = 44
242
+ public static let sidebarWidth: CGFloat = 320
243
+ public static let toolbarHeight: CGFloat = 44
244
+ public static let buttonHeightSm: CGFloat = 30
245
+ public static let buttonHeightMd: CGFloat = 36
246
+ public static let buttonHeightLg: CGFloat = 46
247
+ public static let buttonPaddingXSm: CGFloat = 12
248
+ public static let buttonPaddingXMd: CGFloat = 16
249
+ public static let buttonPaddingXLg: CGFloat = 20
250
+ public static let buttonFontSizeSm: CGFloat = 13
251
+ public static let buttonFontSizeMd: CGFloat = 15
252
+ public static let buttonFontSizeLg: CGFloat = 16
253
+ public static let buttonFontWeight: Int = 600
254
+ public static let buttonRadius: CGFloat = 999
255
+ public static let buttonRadiusSm: CGFloat = 999
256
+ public static let toolbarTitleSize: CGFloat = 17
257
+ public static let panelTabHeight: CGFloat = 36
258
+ public static let glassButtonSize: CGFloat = 44
259
+ public static let segmentedHeight: CGFloat = 28
260
+ public static let segmentedPadding: CGFloat = 2
261
+ public static let segmentedPaddingX: CGFloat = 16
262
+ public static let segmentedFontSize: CGFloat = 14
263
+ public static let segmentedRadius: CGFloat = 999
264
+ public static let fieldHeight: CGFloat = 44
265
+ public static let fieldPaddingX: CGFloat = 12
266
+ public static let fieldFontSize: CGFloat = 17
267
+ public static let fieldRadius: CGFloat = 8
268
+ public static let composerRadius: CGFloat = 24
269
+ public static let composerMinHeight: CGFloat = 44
270
+ public static let rowHeight: CGFloat = 44
271
+ public static let rowPaddingX: CGFloat = 16
272
+ public static let rowRadius: CGFloat = 10
273
+ public static let rowGap: CGFloat = 0
274
+ public static let rowIconSize: CGFloat = 28
275
+ public static let switchWidth: CGFloat = 51
276
+ public static let switchHeight: CGFloat = 31
277
+ public static let cardPaddingX: CGFloat = 16
278
+ public static let cardPaddingY: CGFloat = 14
279
+ public static let cardRadius: CGFloat = 12
280
+ public static let cardGap: CGFloat = 12
281
+ public static let tagHeight: CGFloat = 22
282
+ public static let tagPaddingX: CGFloat = 8
283
+ public static let tagFontSize: CGFloat = 12
284
+ public static let tagRadius: CGFloat = 999
285
+ public static let codeHeaderHeight: CGFloat = 36
286
+ public static let taskRowHeight: CGFloat = 44
287
+ public static let taskGlyphSize: CGFloat = 20
288
+ public static let emptyTitleSize: CGFloat = 20
289
+ public static let emptyIconSize: CGFloat = 36
290
+ public static let toastHeight: CGFloat = 40
291
+ public static let bannerRadius: CGFloat = 12
292
+ public static let sheetRadius: CGFloat = 24
293
+ public static let menuRadius: CGFloat = 12
294
+ public static let messageFontSize: CGFloat = 15
295
+ public static let messageActionSize: CGFloat = 32
296
+ public static let iconSizeSm: CGFloat = 17
297
+ public static let iconSizeMd: CGFloat = 20
298
+ public static let iconSizeLg: CGFloat = 24
299
+ #endif
300
+ }
301
+
302
+ /// 字体角色。iOS 上是文本样式,支持动态字体。
303
+ public extension Font {
304
+ /// 空状态、引导页、页面的大标题(衬线)。每屏最多一个。
305
+ static var deernovaDisplay: Font {
306
+ #if os(macOS)
307
+ .system(size: 26, weight: .semibold, design: .serif)
308
+ #else
309
+ .system(.largeTitle, design: .serif).weight(.semibold)
310
+ #endif
311
+ }
312
+ /// 文章标题、弹窗标题(衬线)。
313
+ static var deernovaTitle: Font {
314
+ #if os(macOS)
315
+ .system(size: 18, weight: .semibold, design: .serif)
316
+ #else
317
+ .system(.title3, design: .serif).weight(.semibold)
318
+ #endif
319
+ }
320
+ /// 区块标题、卡片标题、横幅标题、列表行标题。
321
+ static var deernovaHeadline: Font {
322
+ #if os(macOS)
323
+ .system(size: 15, weight: .semibold)
324
+ #else
325
+ .headline
326
+ #endif
327
+ }
328
+ /// 界面正文、AI 回答、用户消息、列表、表单。
329
+ static var deernovaBody: Font {
330
+ #if os(macOS)
331
+ .system(size: 15)
332
+ #else
333
+ .body
334
+ #endif
335
+ }
336
+ /// 文章、文档这类长文阅读(衬线)。AI 回答不用它。
337
+ static var deernovaProse: Font {
338
+ #if os(macOS)
339
+ .system(size: 16, design: .serif)
340
+ #else
341
+ .system(.body, design: .serif)
342
+ #endif
343
+ }
344
+ /// 说明文字、弹窗正文、输入区下方的模型和权限信息。
345
+ static var deernovaCallout: Font {
346
+ #if os(macOS)
347
+ .system(size: 14)
348
+ #else
349
+ .callout
350
+ #endif
351
+ }
352
+ /// 侧边栏分组标题、分组列表的页头页脚、卡片摘要。
353
+ static var deernovaFootnote: Font {
354
+ #if os(macOS)
355
+ .system(size: 13)
356
+ #else
357
+ .footnote
358
+ #endif
359
+ }
360
+ /// 时间戳、计数、标签。界面里最小的字。
361
+ static var deernovaCaption: Font {
362
+ #if os(macOS)
363
+ .system(size: 12)
364
+ #else
365
+ .caption
366
+ #endif
367
+ }
368
+ /// 代码块、命令、文件路径、需要对齐的数据。
369
+ static var deernovaCode: Font {
370
+ #if os(macOS)
371
+ .system(size: 13, design: .monospaced)
372
+ #else
373
+ .system(.footnote, design: .monospaced)
374
+ #endif
375
+ }
376
+ }
@@ -0,0 +1,106 @@
1
+ /* Generated from tokens.json by `npm run tokens`. Do not edit by hand.
2
+ *
3
+ * Tailwind CSS v4。在全局样式里依次引入:
4
+ * @import "tailwindcss";
5
+ * @import "./tokens.css";
6
+ * @import "./tailwind.css";
7
+ * tokens.css 不要放进 @layer:它要覆盖 Tailwind 默认主题里同名的 --font-*、--radius-*。
8
+ * 用法:bg-surface text-ink border-line、text-body、h-control-md px-button-x-md rounded-button、shadow-float。
9
+ */
10
+
11
+ @theme inline {
12
+ --color-canvas: var(--canvas);
13
+ --color-surface: var(--surface);
14
+ --color-surface-raised: var(--surface-raised);
15
+ --color-surface-sunken: var(--surface-sunken);
16
+ --color-ink: var(--ink);
17
+ --color-ink-secondary: var(--ink-secondary);
18
+ --color-ink-tertiary: var(--ink-tertiary);
19
+ --color-line: var(--line);
20
+ --color-line-control: var(--line-control);
21
+ --color-accent: var(--accent);
22
+ --color-accent-soft: var(--accent-soft);
23
+ --color-on-accent: var(--on-accent);
24
+ --color-focus-ring: var(--focus-ring);
25
+ --color-success: var(--success);
26
+ --color-success-soft: var(--success-soft);
27
+ --color-warning: var(--warning);
28
+ --color-warning-soft: var(--warning-soft);
29
+ --color-danger: var(--danger);
30
+ --color-danger-soft: var(--danger-soft);
31
+ --color-info: var(--info);
32
+ --color-info-soft: var(--info-soft);
33
+ --color-fill-hover: var(--fill-hover);
34
+ --color-fill-selected: var(--fill-selected);
35
+ --color-knob: var(--knob);
36
+ --color-scrim: var(--scrim);
37
+ --color-glass-fill: var(--glass-fill);
38
+ --color-glass-stroke: var(--glass-stroke);
39
+
40
+ --text-display: var(--type-display-size);
41
+ --text-display--line-height: var(--type-display-line);
42
+ --text-display--font-weight: 600;
43
+ --text-title: var(--type-title-size);
44
+ --text-title--line-height: var(--type-title-line);
45
+ --text-title--font-weight: 600;
46
+ --text-headline: var(--type-headline-size);
47
+ --text-headline--line-height: var(--type-headline-line);
48
+ --text-headline--font-weight: 600;
49
+ --text-body: var(--type-body-size);
50
+ --text-body--line-height: var(--type-body-line);
51
+ --text-body--font-weight: 400;
52
+ --text-prose: var(--type-prose-size);
53
+ --text-prose--line-height: var(--type-prose-line);
54
+ --text-prose--font-weight: 400;
55
+ --text-callout: var(--type-callout-size);
56
+ --text-callout--line-height: var(--type-callout-line);
57
+ --text-callout--font-weight: 400;
58
+ --text-footnote: var(--type-footnote-size);
59
+ --text-footnote--line-height: var(--type-footnote-line);
60
+ --text-footnote--font-weight: 400;
61
+ --text-caption: var(--type-caption-size);
62
+ --text-caption--line-height: var(--type-caption-line);
63
+ --text-caption--font-weight: 400;
64
+ --text-code: var(--type-code-size);
65
+ --text-code--line-height: var(--type-code-line);
66
+ --text-code--font-weight: 400;
67
+
68
+ --spacing-control-sm: var(--button-height-sm);
69
+ --spacing-control-md: var(--button-height-md);
70
+ --spacing-control-lg: var(--button-height-lg);
71
+ --spacing-button-x-sm: var(--button-padding-x-sm);
72
+ --spacing-button-x-md: var(--button-padding-x-md);
73
+ --spacing-button-x-lg: var(--button-padding-x-lg);
74
+ --spacing-field: var(--field-height);
75
+ --spacing-row: var(--row-height);
76
+ --spacing-hit: var(--hit-min);
77
+ --spacing-sidebar: var(--sidebar-width);
78
+ --spacing-gap-inline: var(--gap-inline);
79
+ --spacing-gap-stack: var(--gap-stack);
80
+ --spacing-gap-group: var(--gap-group);
81
+ --spacing-page: var(--page-margin);
82
+ --spacing-card-x: var(--card-padding-x);
83
+ --spacing-card-y: var(--card-padding-y);
84
+ --spacing-icon-sm: var(--icon-size-sm);
85
+ --spacing-icon-md: var(--icon-size-md);
86
+ --spacing-icon-lg: var(--icon-size-lg);
87
+ --container-content: var(--content-max);
88
+
89
+ --radius-button: var(--button-radius);
90
+ --radius-button-sm: var(--button-radius-sm);
91
+ --radius-field: var(--field-radius);
92
+ --radius-card: var(--card-radius);
93
+ --radius-tag: var(--tag-radius);
94
+ --radius-menu: var(--menu-radius);
95
+ --radius-sheet: var(--sheet-radius);
96
+ --radius-composer: var(--composer-radius);
97
+ --radius-row: var(--row-radius);
98
+
99
+ --shadow-control: var(--shadow-control);
100
+ --shadow-float: var(--shadow-float);
101
+ --shadow-glass: var(--shadow-glass);
102
+ --ease-standard: var(--ease-standard);
103
+ --default-transition-duration: var(--duration-instant);
104
+ --default-transition-timing-function: var(--ease-standard);
105
+ }
106
+