@deernova/style 0.1.0 → 0.3.0

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 (215) hide show
  1. package/README.md +8 -6
  2. package/bin/cli.mjs +212 -29
  3. package/package.json +3 -4
  4. package/skill/SKILL.md +91 -21
  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 +32 -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
  134. package/template/app.js +0 -7
  135. package/template/index.html +0 -1290
  136. package/template/manifest.json +0 -24
  137. package/template/project/README.md +0 -170
  138. package/template/project/components/Banner/README.md +0 -33
  139. package/template/project/components/Banner/preview.html +0 -26
  140. package/template/project/components/Button/README.md +0 -59
  141. package/template/project/components/Button/preview.html +0 -27
  142. package/template/project/components/Card/README.md +0 -31
  143. package/template/project/components/Card/preview.html +0 -24
  144. package/template/project/components/CodeBlock/README.md +0 -34
  145. package/template/project/components/CodeBlock/preview.html +0 -16
  146. package/template/project/components/Composer/README.md +0 -42
  147. package/template/project/components/Composer/preview.html +0 -28
  148. package/template/project/components/Cover/preview.html +0 -53
  149. package/template/project/components/EmptyState/README.md +0 -28
  150. package/template/project/components/EmptyState/preview.html +0 -16
  151. package/template/project/components/GlassControls/README.md +0 -43
  152. package/template/project/components/GlassControls/preview.html +0 -40
  153. package/template/project/components/ListGroup/README.md +0 -39
  154. package/template/project/components/ListGroup/preview.html +0 -22
  155. package/template/project/components/MacWindow/README.md +0 -27
  156. package/template/project/components/MacWindow/preview.html +0 -70
  157. package/template/project/components/Message/README.md +0 -31
  158. package/template/project/components/Message/preview.html +0 -21
  159. package/template/project/components/PhoneScreen/README.md +0 -25
  160. package/template/project/components/PhoneScreen/preview.html +0 -74
  161. package/template/project/components/Segmented/README.md +0 -21
  162. package/template/project/components/Segmented/preview.html +0 -21
  163. package/template/project/components/Sheet/README.md +0 -29
  164. package/template/project/components/Sheet/preview.html +0 -31
  165. package/template/project/components/Sidebar/README.md +0 -36
  166. package/template/project/components/Sidebar/preview.html +0 -20
  167. package/template/project/components/StepRow/README.md +0 -35
  168. package/template/project/components/StepRow/preview.html +0 -17
  169. package/template/project/components/Tag/README.md +0 -36
  170. package/template/project/components/Tag/preview.html +0 -22
  171. package/template/project/components/TextField/README.md +0 -29
  172. package/template/project/components/TextField/preview.html +0 -28
  173. package/template/project/components/bundle.css +0 -189
  174. package/template/project/design-system.json +0 -25
  175. package/template/project/images/Banner-dark.png +0 -0
  176. package/template/project/images/Banner-light.png +0 -0
  177. package/template/project/images/Button-dark.png +0 -0
  178. package/template/project/images/Button-light.png +0 -0
  179. package/template/project/images/Card-dark.png +0 -0
  180. package/template/project/images/Card-light.png +0 -0
  181. package/template/project/images/CodeBlock-dark.png +0 -0
  182. package/template/project/images/CodeBlock-light.png +0 -0
  183. package/template/project/images/Composer-dark.png +0 -0
  184. package/template/project/images/Composer-light.png +0 -0
  185. package/template/project/images/Cover-dark.png +0 -0
  186. package/template/project/images/Cover-light.png +0 -0
  187. package/template/project/images/EmptyState-dark.png +0 -0
  188. package/template/project/images/EmptyState-light.png +0 -0
  189. package/template/project/images/Example-iOSButtonsInPhone-dark.png +0 -0
  190. package/template/project/images/Example-iOSButtonsInPhone-light.png +0 -0
  191. package/template/project/images/GlassControls-dark.png +0 -0
  192. package/template/project/images/GlassControls-light.png +0 -0
  193. package/template/project/images/ListGroup-dark.png +0 -0
  194. package/template/project/images/ListGroup-light.png +0 -0
  195. package/template/project/images/MacWindow-dark.png +0 -0
  196. package/template/project/images/MacWindow-light.png +0 -0
  197. package/template/project/images/Message-dark.png +0 -0
  198. package/template/project/images/Message-light.png +0 -0
  199. package/template/project/images/PhoneScreen-dark.png +0 -0
  200. package/template/project/images/PhoneScreen-light.png +0 -0
  201. package/template/project/images/Segmented-dark.png +0 -0
  202. package/template/project/images/Segmented-light.png +0 -0
  203. package/template/project/images/Sheet-dark.png +0 -0
  204. package/template/project/images/Sheet-light.png +0 -0
  205. package/template/project/images/Sidebar-dark.png +0 -0
  206. package/template/project/images/Sidebar-light.png +0 -0
  207. package/template/project/images/StepRow-dark.png +0 -0
  208. package/template/project/images/StepRow-light.png +0 -0
  209. package/template/project/images/Tag-dark.png +0 -0
  210. package/template/project/images/Tag-light.png +0 -0
  211. package/template/project/images/TextField-dark.png +0 -0
  212. package/template/project/images/TextField-light.png +0 -0
  213. package/template/project/tokens.css +0 -187
  214. package/template/project/tokens.json +0 -142
  215. package/template/style.css +0 -1
@@ -1,35 +0,0 @@
1
- # StepRow
2
-
3
- 一行显示一个执行步骤:做了什么、结果如何、用了多久。点开可以看到细节。用于 AI 的工具调用、导入导出、批量处理这类任务。
4
-
5
- **需要提供**:状态(进行中 / 成功 / 失败)、动作名(2–4 个字的动词)、对象摘要(文件名、参数、结果)、耗时或说明;可选的详细内容,点击后展开。
6
-
7
- **规格**
8
-
9
- - 高 `control-mac`,`radius-sm`,悬停时底色 `fill-hover`。整行默认 `ink-secondary`,让位于正文内容。
10
- - 状态图标 14pt:进行中是 `ink` 色的转圈,成功是 `success` 色,失败是 `danger` 色。失败时摘要要写清楚原因。
11
- - 动作名 12pt 半粗 `ink`;摘要用 11pt 等宽,单行,在末尾截断;右侧耗时 11pt `ink-tertiary`。
12
- - 展开后的详情缩进到和文字对齐,`surface-sunken` 底,`radius-sm`,12pt 等宽。
13
- - 连续 3 步以上全部成功时,合并成一行「完成 5 个步骤」,点击后展开。
14
-
15
- ```swift
16
- DisclosureGroup(isExpanded: $expanded) {
17
- Text(step.detail)
18
- .font(.system(.callout, design: .monospaced))
19
- .foregroundStyle(.inkSecondary)
20
- .padding(.vertical, 6).padding(.horizontal, 8)
21
- .frame(maxWidth: .infinity, alignment: .leading)
22
- .background(.surfaceSunken, in: .rect(cornerRadius: 6))
23
- } label: {
24
- HStack(spacing: 7) {
25
- StatusGlyph(step.status) // ProgressView / checkmark.circle / xmark.circle
26
- Text(step.action).fontWeight(.semibold).foregroundStyle(.ink)
27
- Text(step.summary).font(.callout.monospaced()).lineLimit(1)
28
- Spacer()
29
- Text(step.duration).font(.caption).monospacedDigit().foregroundStyle(.inkTertiary)
30
- }
31
- .foregroundStyle(.inkSecondary)
32
- }
33
- ```
34
-
35
- **不要**:把每一步都做成卡片;成功的步骤也用醒目的颜色;把原始日志直接铺在对话里(放进折叠详情)。
@@ -1,17 +0,0 @@
1
- <!-- @dsCard group="Content" height=190 subtitle="AI 或后台任务的执行步骤" -->
2
- <!doctype html>
3
- <html lang="zh-CN">
4
- <head><link rel="stylesheet" href="../../tokens.css"><link rel="stylesheet" href="../bundle.css"><script>(function(){function a(){var t=location.hash.slice(1),r=document.documentElement;if(t==="light"||t==="dark")r.setAttribute("data-theme",t);else r.removeAttribute("data-theme");}a();addEventListener("hashchange",a);})();</script><meta charset="utf-8"><title>StepRow</title></head>
5
- <body>
6
- <div class="dn-stage" style="justify-content:center">
7
- <div class="dn-steps">
8
- <div class="dn-step dn-step-ok"><svg class="dn-icon dn-glyph" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M8 12.5l2.5 2.5L16 9.5"/></svg><span class="dn-step-name">读取</span><span class="dn-step-text">周报草稿.md、10 月数据.csv</span><span class="dn-step-meta">0.4 秒</span><svg class="dn-icon dn-chevron" viewBox="0 0 24 24"><path d="M9 6l6 6-6 6"/></svg></div>
9
- <div class="dn-step dn-step-ok"><svg class="dn-icon dn-glyph" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M8 12.5l2.5 2.5L16 9.5"/></svg><span class="dn-step-name">计算</span><span class="dn-step-text">订阅转化率 3.1% → 4.4%</span><span class="dn-step-meta">1.2 秒</span><svg class="dn-icon dn-chevron" viewBox="0 0 24 24"><path d="M6 9l6 6 6-6"/></svg></div>
10
- <div class="dn-step-detail">conversions / trials = 88 / 2000 = 4.4%
11
- 上月 = 62 / 2000 = 3.1%</div>
12
- <div class="dn-step dn-step-fail"><svg class="dn-icon dn-glyph" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M9 9l6 6M15 9l-6 6"/></svg><span class="dn-step-name">读取</span><span class="dn-step-text">销售日报.xlsx:文件已被移动或删除</span><span class="dn-step-meta">已跳过</span></div>
13
- <div class="dn-step"><span class="dn-spinner" role="img" aria-label="进行中"></span><span class="dn-step-name">整理</span><span class="dn-step-text">生成三条要点</span><span class="dn-step-meta">3.0 秒</span></div>
14
- </div>
15
- </div>
16
- </body>
17
- </html>
@@ -1,36 +0,0 @@
1
- # Tag
2
-
3
- 一到四个字的标签,标出状态或分类,放在标题旁边或元信息里。
4
-
5
- **需要提供**:文字、语气(中性 / 强调 / success / warning / danger / info);表示状态时加一个圆点。
6
-
7
- **规格**
8
-
9
- - Mac:高 18pt,`radius-xs`,11pt 中粗,左右内边距 6pt。iOS:高 22pt,胶囊形,12pt。
10
- - 中性标签:`fill-selected` 底、`ink-secondary` 字。强调标签:`accent` 黑底、`on-accent` 白字,只用于「新」「Pro」这类需要跳出来的少数标记。有语气的标签:用对应的 `-soft` 作底色,用语气色作文字和圆点,例如 `success-soft` 底配 `success` 字。
11
- - 表示状态时一定加 5pt 圆点(`radius-full`),文字本身就要说清楚状态是什么,不能只靠颜色。
12
-
13
- ```swift
14
- struct Tag: View {
15
- var text: LocalizedStringKey
16
- var tone: Color = .inkSecondary
17
- var background: Color = .fillSelected
18
- var showsDot = false
19
-
20
- var body: some View {
21
- HStack(spacing: 4) {
22
- if showsDot { Circle().frame(width: 5, height: 5) }
23
- Text(text)
24
- }
25
- .font(.caption.weight(.medium))
26
- .foregroundStyle(tone)
27
- .padding(.horizontal, 6)
28
- .frame(height: 18)
29
- .background(background, in: .rect(cornerRadius: 4))
30
- }
31
- }
32
-
33
- Tag(text: "已同步", tone: .success, background: .successSoft, showsDot: true)
34
- ```
35
-
36
- **不要**:用标签当按钮;一行里放超过三个标签;大量使用黑底强调标签(它和主按钮长得像,多了就分不清)。
@@ -1,22 +0,0 @@
1
- <!-- @dsCard group="Feedback" height=120 subtitle="状态与分类" -->
2
- <!doctype html>
3
- <html lang="zh-CN">
4
- <head><link rel="stylesheet" href="../../tokens.css"><link rel="stylesheet" href="../bundle.css"><script>(function(){function a(){var t=location.hash.slice(1),r=document.documentElement;if(t==="light"||t==="dark")r.setAttribute("data-theme",t);else r.removeAttribute("data-theme");}a();addEventListener("hashchange",a);})();</script><meta charset="utf-8"><title>Tag</title></head>
5
- <body>
6
- <div class="dn-stage dn-stack" style="align-items:flex-start">
7
- <div class="dn-row">
8
- <span class="dn-tag">草稿</span>
9
- <span class="dn-tag dn-tag-accent">新功能</span>
10
- <span class="dn-tag dn-tag-success"><span class="dn-dot"></span>已同步</span>
11
- <span class="dn-tag dn-tag-warning"><span class="dn-dot"></span>额度剩余 10%</span>
12
- <span class="dn-tag dn-tag-danger"><span class="dn-dot"></span>同步失败</span>
13
- <span class="dn-tag dn-tag-info">Beta</span>
14
- </div>
15
- <div class="dn-row">
16
- <span class="dn-tag dn-tag-ios">工作</span>
17
- <span class="dn-tag dn-tag-ios dn-tag-success"><span class="dn-dot"></span>已完成</span>
18
- <span class="dn-tag dn-tag-ios dn-tag-accent">全家桶</span>
19
- </div>
20
- </div>
21
- </body>
22
- </html>
@@ -1,29 +0,0 @@
1
- # TextField
2
-
3
- 单行文字输入,配一个标签和一句说明。
4
-
5
- **需要提供**:标签(名词)、绑定的文本、可选的占位符(给示例,不要重复标签)、说明文字,校验失败时提供错误信息。
6
-
7
- **规格**
8
-
9
- - 底色 `surface-raised`,边框 `stroke-control` 宽、`line-control` 色。Mac 用 `radius-sm`,高 `control-mac`;iOS 用 `radius-md`,高 `control-ios`。
10
- - 聚焦时边框变 `focus-ring`,外圈加 3pt 的 `accent-soft` 灰色光晕。
11
- - 出错时边框变 `danger`,说明文字换成错误信息,同样用 `danger` 色。错误信息要说清楚怎么改。
12
- - 标签 12pt 中粗 `ink-secondary`,放在输入框上方;说明 11pt `ink-tertiary`,放在下方。
13
-
14
- ```swift
15
- VStack(alignment: .leading, spacing: 6) {
16
- Text("邮箱").font(.caption.weight(.medium)).foregroundStyle(.inkSecondary)
17
- TextField("name@example.com", text: $email)
18
- .textFieldStyle(.roundedBorder) // Mac;iOS 用自定义样式实现上面的规格
19
- .textContentType(.emailAddress)
20
- .keyboardType(.emailAddress) // iOS
21
- Text(error ?? "用于接收登录验证码。")
22
- .font(.caption)
23
- .foregroundStyle(error == nil ? .inkTertiary : .danger)
24
- }
25
- ```
26
-
27
- iOS 设置页这类表单,直接在 `Form` 里用 `TextField`,交给系统的分组样式(见 ListGroup)。
28
-
29
- **不要**:只用占位符代替标签;出错时只把边框变红、不给说明;把多行输入塞进单行框(多行用 `TextField(axis: .vertical)` 或 Composer)。
@@ -1,28 +0,0 @@
1
- <!-- @dsCard group="Input" height=180 subtitle="单行输入" -->
2
- <!doctype html>
3
- <html lang="zh-CN">
4
- <head><link rel="stylesheet" href="../../tokens.css"><link rel="stylesheet" href="../bundle.css"><script>(function(){function a(){var t=location.hash.slice(1),r=document.documentElement;if(t==="light"||t==="dark")r.setAttribute("data-theme",t);else r.removeAttribute("data-theme");}a();addEventListener("hashchange",a);})();</script><meta charset="utf-8"><title>TextField</title></head>
5
- <body>
6
- <div class="dn-stage" style="align-items:flex-start;gap:var(--space-5)">
7
- <div class="dn-field">
8
- <label for="f1">名称</label>
9
- <input id="f1" class="dn-input" placeholder="例如:读书摘录">
10
- <span class="dn-help">会显示在侧边栏里。</span>
11
- </div>
12
- <div class="dn-field">
13
- <label for="f2">邮箱</label>
14
- <input id="f2" class="dn-input is-focus" value="hello@paperlight.app">
15
- <span class="dn-help">用于接收登录验证码。</span>
16
- </div>
17
- <div class="dn-field">
18
- <label for="f3">验证码</label>
19
- <input id="f3" class="dn-input is-error" value="12 34">
20
- <span class="dn-help is-error">验证码是 6 位数字,请检查后重新输入。</span>
21
- </div>
22
- <div class="dn-field" style="width:300px">
23
- <label for="f4">iOS · 44pt</label>
24
- <input id="f4" class="dn-input dn-input-ios" placeholder="搜索笔记">
25
- </div>
26
- </div>
27
- </body>
28
- </html>
@@ -1,189 +0,0 @@
1
- /* Deernova: web approximations of the SwiftUI components, used by the previews */
2
- * { box-sizing: border-box; }
3
- html, body { margin: 0; }
4
- body { font-family: var(--font-sans); font-size: 13px; line-height: 18px; background: var(--canvas); color: var(--ink); -webkit-font-smoothing: antialiased; }
5
-
6
- .dn-stage { padding: var(--space-4); display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
7
- .dn-stack { display: flex; flex-direction: column; gap: var(--space-2); }
8
- .dn-row { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
9
- .dn-note { font-size: 11px; line-height: 13px; color: var(--ink-tertiary); }
10
- .dn-icon { width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
11
-
12
- /* Button */
13
- .dn-btn { appearance: none; display: inline-flex; align-items: center; justify-content: center; gap: 5px; height: var(--control-mac); padding: 0 var(--space-3); font: inherit; font-size: 13px; font-weight: 500; line-height: 1; white-space: nowrap; border-radius: var(--radius-sm); border: var(--stroke-hairline) solid var(--line); background: var(--surface-raised); color: var(--ink); box-shadow: var(--shadow-control); cursor: pointer; }
14
- .dn-btn:hover { background: var(--surface); }
15
- .dn-btn:focus-visible, .dn-btn.is-focus { outline: var(--stroke-focus) solid var(--focus-ring); outline-offset: 2px; }
16
- .dn-btn-primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
17
- .dn-btn-primary:hover { background: var(--accent); opacity: 0.88; }
18
- .dn-btn-plain { background: transparent; border-color: transparent; box-shadow: none; color: var(--ink-secondary); }
19
- .dn-btn-plain:hover { background: var(--fill-hover); color: var(--ink); }
20
- .dn-btn-danger { background: var(--danger-soft); border-color: transparent; box-shadow: none; color: var(--danger); }
21
- .dn-btn-danger:hover { background: var(--danger-soft); filter: brightness(0.97); }
22
- .dn-btn-sm { height: var(--control-mac-sm); padding: 0 var(--space-2); font-size: 11px; border-radius: var(--radius-xs); }
23
- .dn-btn-lg { height: var(--control-mac-lg); padding: 0 var(--space-4); }
24
- .dn-btn-ios { height: var(--button-ios); padding: 0 var(--space-4); font-size: 15px; font-weight: 600; border-radius: var(--radius-full); }
25
- .dn-btn-ios-sm { height: var(--button-ios-sm); padding: 0 var(--space-3); font-size: 13px; font-weight: 600; border-radius: var(--radius-full); }
26
- .dn-btn-ios-lg { height: var(--control-ios-lg); width: 100%; padding: 0 var(--space-5); font-size: 16px; font-weight: 600; border-radius: var(--radius-full); }
27
- .dn-btn[disabled] { opacity: 0.35; cursor: default; filter: none; }
28
- .dn-btn .dn-icon { width: 13px; height: 13px; }
29
-
30
- .dn-iconbtn { appearance: none; width: var(--control-mac); height: var(--control-mac); padding: 0; border-radius: var(--radius-sm); border: 0; background: transparent; color: var(--ink-secondary); display: inline-grid; place-items: center; cursor: pointer; flex: none; }
31
- .dn-iconbtn:hover { background: var(--fill-hover); color: var(--ink); }
32
- .dn-iconbtn:focus-visible { outline: var(--stroke-focus) solid var(--focus-ring); outline-offset: 1px; }
33
-
34
- /* Glass: web approximation of .glassEffect() */
35
- .dn-backdrop { position: relative; overflow: hidden; background: var(--surface); }
36
- .dn-glass { background: var(--glass-fill); -webkit-backdrop-filter: blur(14px) saturate(1.4); backdrop-filter: blur(14px) saturate(1.4); border: var(--stroke-hairline) solid var(--glass-stroke); box-shadow: var(--shadow-glass); border-radius: var(--radius-full); }
37
- .dn-glass-btn { appearance: none; width: var(--control-ios); height: var(--control-ios); padding: 0; display: inline-grid; place-items: center; color: var(--ink); cursor: pointer; font: inherit; flex: none; }
38
- .dn-glass-btn .dn-icon { width: 19px; height: 19px; }
39
- .dn-glass-prominent { background: var(--accent); color: var(--on-accent); border-color: transparent; }
40
- .dn-glass-group { display: inline-flex; align-items: center; gap: 2px; padding: 3px; }
41
- .dn-glass-group .dn-glass-btn { background: transparent; border: 0; box-shadow: none; width: 36px; height: 36px; border-radius: var(--radius-full); color: var(--ink-secondary); }
42
- .dn-glass-group .dn-glass-btn.is-selected { background: var(--fill-selected); color: var(--ink); }
43
- .dn-glass-pill { height: 40px; padding: 0 var(--space-4); display: inline-flex; align-items: center; gap: var(--space-2); font-size: 14px; font-weight: 500; color: var(--ink); }
44
-
45
- /* Segmented */
46
- .dn-seg { display: inline-flex; padding: 2px; gap: 2px; background: var(--fill-selected); border-radius: var(--radius-sm); }
47
- .dn-seg button { appearance: none; border: 0; font: inherit; font-size: 12px; font-weight: 500; height: var(--control-mac-sm); padding: 0 var(--space-3); border-radius: var(--radius-xs); background: transparent; color: var(--ink-secondary); cursor: pointer; }
48
- .dn-seg button[aria-pressed="true"] { background: var(--surface-raised); color: var(--ink); box-shadow: var(--shadow-control); }
49
- .dn-seg-ios { padding: 2px; border-radius: var(--radius-full); }
50
- .dn-seg-ios button { height: 30px; padding: 0 var(--space-4); font-size: 14px; border-radius: var(--radius-full); }
51
-
52
- /* Text field */
53
- .dn-field { display: flex; flex-direction: column; gap: 4px; width: 240px; max-width: 100%; }
54
- .dn-field label { font-size: 12px; line-height: 16px; font-weight: 500; color: var(--ink-secondary); }
55
- .dn-input { height: var(--control-mac); padding: 0 var(--space-2); font: inherit; font-size: 13px; color: var(--ink); background: var(--surface-raised); border: var(--stroke-control) solid var(--line-control); border-radius: var(--radius-sm); outline: none; width: 100%; }
56
- .dn-input::placeholder { color: var(--ink-tertiary); }
57
- .dn-input:focus, .dn-input.is-focus { border-color: var(--focus-ring); box-shadow: 0 0 0 3px var(--accent-soft); }
58
- .dn-input.is-error { border-color: var(--danger); }
59
- .dn-input-ios { height: var(--control-ios); padding: 0 var(--space-3); font-size: 17px; border-radius: var(--radius-md); }
60
- .dn-help { font-size: 11px; line-height: 13px; color: var(--ink-tertiary); }
61
- .dn-help.is-error { color: var(--danger); }
62
-
63
- /* Composer */
64
- .dn-composer { width: 100%; max-width: 560px; background: var(--surface-raised); border: var(--stroke-hairline) solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-float); padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3); display: flex; flex-direction: column; gap: var(--space-1); }
65
- .dn-composer textarea { border: 0; outline: none; resize: none; background: transparent; font: inherit; font-size: 13px; line-height: 18px; color: var(--ink); min-height: 36px; padding: 2px 0; width: 100%; }
66
- .dn-composer textarea::placeholder { color: var(--ink-tertiary); }
67
- .dn-composer:focus-within { border-color: var(--line-control); }
68
- .dn-composer-bar { display: flex; align-items: center; gap: var(--space-1); margin-left: -4px; }
69
- .dn-spacer { flex: 1; }
70
- .dn-chip { display: inline-flex; align-items: center; gap: 3px; height: var(--control-mac-sm); padding: 0 var(--space-2); border-radius: var(--radius-full); font: inherit; font-size: 11px; color: var(--ink-secondary); background: transparent; border: var(--stroke-hairline) solid var(--line); cursor: pointer; white-space: nowrap; }
71
- .dn-chip .dn-icon { width: 11px; height: 11px; }
72
- .dn-send { appearance: none; width: var(--control-mac); height: var(--control-mac); padding: 0; border-radius: var(--radius-full); border: 0; display: grid; place-items: center; background: var(--accent); color: var(--on-accent); cursor: pointer; flex: none; }
73
- .dn-send .dn-icon { width: 13px; height: 13px; stroke-width: 2.2; }
74
- .dn-send[disabled] { background: var(--fill-selected); color: var(--ink-tertiary); cursor: default; }
75
- .dn-attach { display: inline-flex; align-items: center; gap: 5px; height: var(--control-mac); padding: 0 var(--space-2); border-radius: var(--radius-sm); background: var(--surface-sunken); font-size: 12px; color: var(--ink-secondary); align-self: flex-start; }
76
-
77
- /* Sidebar (macOS) */
78
- .dn-sidebar { width: var(--sidebar-mac); background: var(--surface-sunken); border: var(--stroke-hairline) solid var(--line); border-radius: var(--radius-lg); padding: 6px; display: flex; flex-direction: column; gap: 1px; }
79
- .dn-side-head { font-size: 11px; line-height: 13px; font-weight: 600; color: var(--ink-tertiary); padding: var(--space-3) var(--space-2) var(--space-1); }
80
- .dn-side-item { display: flex; align-items: center; gap: 7px; height: var(--row-mac); padding: 0 var(--space-2); border-radius: var(--radius-sm); font-size: 13px; color: var(--ink); cursor: default; min-width: 0; }
81
- .dn-side-item .dn-icon { width: 14px; height: 14px; color: var(--ink-secondary); }
82
- .dn-side-item:hover { background: var(--fill-hover); }
83
- .dn-side-item.is-selected { background: var(--fill-selected); font-weight: 500; }
84
- .dn-side-item.is-selected .dn-icon { color: var(--ink); }
85
- .dn-side-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
86
- .dn-count { margin-left: auto; font-size: 11px; color: var(--ink-tertiary); font-variant-numeric: tabular-nums; }
87
-
88
- /* List group (iOS inset grouped) */
89
- .dn-listwrap { background: var(--canvas); padding: var(--space-4); width: 375px; max-width: 100%; display: flex; flex-direction: column; }
90
- .dn-list-head { font-size: 13px; line-height: 17px; color: var(--ink-secondary); padding: 0 var(--space-4) 6px; }
91
- .dn-list { background: var(--surface-raised); border-radius: var(--radius-lg); overflow: hidden; }
92
- .dn-list-row { --sep-inset: var(--space-4); display: flex; align-items: center; gap: var(--space-3); min-height: var(--control-ios); padding: 0 var(--space-4); font-size: 17px; line-height: 22px; color: var(--ink); position: relative; }
93
- .dn-list-row.has-icon { --sep-inset: 56px; }
94
- .dn-list-row + .dn-list-row::before { content: ""; position: absolute; top: 0; left: var(--sep-inset); right: 0; border-top: var(--stroke-hairline) solid var(--line); }
95
- .dn-list-icon { width: 28px; height: 28px; border-radius: var(--radius-sm); display: grid; place-items: center; background: var(--accent-soft); color: var(--ink); flex: none; }
96
- .dn-list-icon .dn-icon { width: 16px; height: 16px; }
97
- .dn-list-value { margin-left: auto; color: var(--ink-secondary); white-space: nowrap; }
98
- .dn-chevron { color: var(--ink-tertiary); width: 13px; height: 13px; }
99
- .dn-list-foot { font-size: 13px; line-height: 17px; color: var(--ink-tertiary); padding: 6px var(--space-4) 0; }
100
- .dn-switch { margin-left: auto; width: 51px; height: 31px; border-radius: var(--radius-full); background: var(--success); position: relative; flex: none; }
101
- .dn-switch::after { content: ""; position: absolute; top: 2px; right: 2px; width: 27px; height: 27px; border-radius: var(--radius-full); background: var(--knob); box-shadow: var(--shadow-control); }
102
- .dn-switch.is-off { background: var(--fill-selected); }
103
- .dn-switch.is-off::after { right: auto; left: 2px; }
104
-
105
- /* Card */
106
- .dn-card { background: var(--surface); border: var(--stroke-hairline) solid var(--line); border-radius: var(--radius-md); padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-1); width: 240px; max-width: 100%; }
107
- .dn-card-title { font-family: var(--font-serif); font-size: 15px; line-height: 20px; font-weight: 600; color: var(--ink); margin: 0; }
108
- .dn-card-body { font-size: 12px; line-height: 17px; color: var(--ink-secondary); margin: 0; }
109
- .dn-card-meta { font-size: 11px; line-height: 13px; color: var(--ink-tertiary); display: flex; gap: 6px; align-items: center; margin-top: 2px; font-variant-numeric: tabular-nums; }
110
- .dn-card.is-interactive { cursor: pointer; }
111
- .dn-card.is-interactive:hover { border-color: var(--line-control); }
112
- .dn-card.is-selected { border-color: var(--accent); box-shadow: inset 0 0 0 0.5px var(--accent); }
113
-
114
- /* Tag */
115
- .dn-tag { display: inline-flex; align-items: center; gap: 4px; height: 18px; padding: 0 6px; border-radius: var(--radius-xs); font-size: 11px; font-weight: 500; line-height: 1; white-space: nowrap; background: var(--fill-selected); color: var(--ink-secondary); }
116
- .dn-tag-accent { background: var(--accent); color: var(--on-accent); }
117
- .dn-tag-success { background: var(--success-soft); color: var(--success); }
118
- .dn-tag-warning { background: var(--warning-soft); color: var(--warning); }
119
- .dn-tag-danger { background: var(--danger-soft); color: var(--danger); }
120
- .dn-tag-info { background: var(--info-soft); color: var(--info); }
121
- .dn-dot { width: 5px; height: 5px; border-radius: var(--radius-full); background: currentColor; flex: none; }
122
- .dn-tag-ios { height: 22px; padding: 0 var(--space-2); font-size: 12px; border-radius: var(--radius-full); }
123
-
124
- /* Banner and toast */
125
- .dn-banner { display: flex; gap: 10px; align-items: flex-start; padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); background: var(--surface-raised); border: var(--stroke-hairline) solid var(--line); width: 100%; max-width: 520px; }
126
- .dn-banner > .dn-icon { width: 16px; height: 16px; margin-top: 1px; color: var(--ink-secondary); }
127
- .dn-banner-text { flex: 1; min-width: 0; }
128
- .dn-banner-title { font-size: 13px; line-height: 18px; font-weight: 600; color: var(--ink); margin: 0; }
129
- .dn-banner-body { font-size: 12px; line-height: 17px; color: var(--ink-secondary); margin: 0; }
130
- .dn-banner-success { background: var(--success-soft); border-color: transparent; }
131
- .dn-banner-success > .dn-icon { color: var(--success); }
132
- .dn-banner-warning { background: var(--warning-soft); border-color: transparent; }
133
- .dn-banner-warning > .dn-icon { color: var(--warning); }
134
- .dn-banner-danger { background: var(--danger-soft); border-color: transparent; }
135
- .dn-banner-danger > .dn-icon { color: var(--danger); }
136
- .dn-toast { display: inline-flex; align-items: center; gap: var(--space-2); height: 40px; padding: 0 var(--space-4) 0 var(--space-3); font-size: 14px; font-weight: 500; color: var(--ink); }
137
- .dn-toast .dn-icon { width: 16px; height: 16px; color: var(--success); }
138
-
139
- /* Message */
140
- .dn-thread { display: flex; flex-direction: column; gap: var(--space-4); width: 100%; max-width: 600px; }
141
- .dn-msg-user { align-self: flex-end; max-width: 80%; background: var(--surface-sunken); border-radius: var(--radius-lg); padding: 6px var(--space-3); font-size: 13px; line-height: 18px; color: var(--ink); }
142
- .dn-msg-assistant { font-family: var(--font-serif); font-size: 14px; line-height: 22px; color: var(--ink); }
143
- .dn-msg-assistant p { margin: 0 0 var(--space-2); }
144
- .dn-msg-assistant p:last-of-type { margin-bottom: 0; }
145
- .dn-msg-assistant strong { font-weight: 600; }
146
- .dn-msg-assistant a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; text-decoration-color: var(--line-control); }
147
- .dn-msg-actions { display: flex; gap: 2px; margin-top: var(--space-1); margin-left: -5px; }
148
- .dn-msg-actions .dn-iconbtn { width: 22px; height: 22px; color: var(--ink-tertiary); }
149
- .dn-msg-actions .dn-icon { width: 13px; height: 13px; }
150
-
151
- /* Code block */
152
- .dn-code { background: var(--surface-sunken); border: var(--stroke-hairline) solid var(--line); border-radius: var(--radius-md); overflow: hidden; width: 100%; max-width: 560px; }
153
- .dn-code-head { display: flex; align-items: center; height: 28px; padding: 0 var(--space-1) 0 var(--space-3); border-bottom: var(--stroke-hairline) solid var(--line); font-family: var(--font-mono); font-size: 11px; color: var(--ink-tertiary); }
154
- .dn-code-head .dn-btn { margin-left: auto; }
155
- .dn-code pre { margin: 0; padding: var(--space-2) var(--space-3); overflow-x: auto; font-family: var(--font-mono); font-size: 12px; line-height: 17px; color: var(--ink); }
156
- .tk-kw { color: var(--ink); font-weight: 600; }
157
- .tk-str { color: var(--ink-secondary); }
158
- .tk-num { color: var(--ink); }
159
- .tk-com { color: var(--ink-tertiary); font-style: italic; }
160
- .tk-type { color: var(--ink); }
161
-
162
- /* Step row */
163
- .dn-steps { display: flex; flex-direction: column; width: 100%; max-width: 560px; }
164
- .dn-step { display: flex; align-items: center; gap: 7px; height: var(--control-mac); padding: 0 6px; border-radius: var(--radius-sm); font-size: 12px; color: var(--ink-secondary); cursor: default; min-width: 0; }
165
- .dn-step:hover { background: var(--fill-hover); }
166
- .dn-step .dn-icon { width: 14px; height: 14px; }
167
- .dn-step-name { font-weight: 600; color: var(--ink); white-space: nowrap; }
168
- .dn-step-text { font-family: var(--font-mono); font-size: 11px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
169
- .dn-step-meta { margin-left: auto; padding-left: var(--space-2); font-size: 11px; color: var(--ink-tertiary); font-variant-numeric: tabular-nums; white-space: nowrap; }
170
- .dn-step-ok .dn-glyph { color: var(--success); }
171
- .dn-step-fail .dn-glyph { color: var(--danger); }
172
- .dn-step .dn-chevron { color: var(--ink-tertiary); width: 11px; height: 11px; }
173
- .dn-step-detail { margin: 2px 0 6px 27px; padding: 6px var(--space-2); background: var(--surface-sunken); border-radius: var(--radius-sm); font-family: var(--font-mono); font-size: 11px; line-height: 16px; color: var(--ink-secondary); white-space: pre-wrap; }
174
- .dn-spinner { width: 13px; height: 13px; border-radius: var(--radius-full); border: 2px solid var(--line); border-top-color: var(--ink); animation: dn-spin 0.9s linear infinite; flex: none; }
175
- @keyframes dn-spin { to { transform: rotate(360deg); } }
176
- @media (prefers-reduced-motion: reduce) { .dn-spinner { animation-duration: 2.4s; } }
177
-
178
- /* Empty state */
179
- .dn-empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--space-1); padding: var(--space-6) var(--space-5); }
180
- .dn-empty > .dn-icon { width: 28px; height: 28px; color: var(--ink-tertiary); stroke-width: 1.4; }
181
- .dn-empty h2 { font-family: var(--font-serif); font-size: 22px; line-height: 28px; font-weight: 600; letter-spacing: -0.01em; margin: var(--space-2) 0 0; color: var(--ink); }
182
- .dn-empty p { margin: 0 0 var(--space-3); max-width: 320px; color: var(--ink-secondary); font-size: 13px; line-height: 18px; }
183
-
184
- /* Sheet (iOS) */
185
- .dn-sheet { width: 359px; max-width: 100%; border-radius: var(--radius-xl); padding: var(--space-2) var(--space-5) var(--space-5); }
186
- .dn-grabber { width: 36px; height: 5px; border-radius: var(--radius-full); background: var(--line-control); margin: 0 auto var(--space-3); }
187
- .dn-sheet h3 { font-family: var(--font-serif); font-size: 20px; line-height: 25px; font-weight: 600; margin: 0 0 var(--space-1); color: var(--ink); }
188
- .dn-sheet p { font-size: 15px; line-height: 20px; color: var(--ink-secondary); margin: 0 0 var(--space-4); }
189
- .dn-sheet .dn-stack { gap: var(--space-1); }
@@ -1,25 +0,0 @@
1
- {
2
- "v": 3,
3
- "assetGroups": {},
4
- "blobs": {},
5
- "createdOnFiles": {
6
- "at": "2026-10-31T17:19:19Z",
7
- "v": 1
8
- },
9
- "docs": {
10
- "readme": "project/README.md",
11
- "sections": []
12
- },
13
- "groups": [],
14
- "lastChange": {
15
- "by": "Claude",
16
- "via": "Claude Code",
17
- "at": "2026-11-01T13:33:31Z",
18
- "note": "修正 Composer、TextField、MacWindow、Button 预览被裁掉底部的问题。"
19
- },
20
- "layout": "files",
21
- "libraries": [],
22
- "namespace": "Deernova",
23
- "sections": {},
24
- "title": "Deernova"
25
- }