@once-ui-system/core 1.7.11 → 1.7.12

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 (325) hide show
  1. package/ai/catalog.json +1650 -0
  2. package/ai/catalog.seed.json +411 -0
  3. package/ai/components/Accordion.json +136 -0
  4. package/ai/components/AccordionGroup.json +128 -0
  5. package/ai/components/Animation.json +146 -0
  6. package/ai/components/Arrow.json +128 -0
  7. package/ai/components/AutoScroll.json +130 -0
  8. package/ai/components/Avatar.json +133 -0
  9. package/ai/components/AvatarGroup.json +129 -0
  10. package/ai/components/Background.json +131 -0
  11. package/ai/components/Badge.json +132 -0
  12. package/ai/components/Banner.json +122 -0
  13. package/ai/components/BarChart.json +123 -0
  14. package/ai/components/BlobFx.json +125 -0
  15. package/ai/components/BlockQuote.json +132 -0
  16. package/ai/components/Button.json +26 -0
  17. package/ai/components/Card.json +129 -0
  18. package/ai/components/Carousel.json +134 -0
  19. package/ai/components/CelebrationFx.json +132 -0
  20. package/ai/components/ChartHeader.json +130 -0
  21. package/ai/components/ChartStatus.json +12 -0
  22. package/ai/components/Checkbox.json +13 -0
  23. package/ai/components/Chip.json +132 -0
  24. package/ai/components/CodeBlock.json +122 -0
  25. package/ai/components/ColorInput.json +13 -0
  26. package/ai/components/Column.json +128 -0
  27. package/ai/components/CompareImage.json +126 -0
  28. package/ai/components/ContextMenu.json +22 -0
  29. package/ai/components/CountFx.json +82 -0
  30. package/ai/components/CountdownFx.json +11 -0
  31. package/ai/components/Cursor.json +9 -0
  32. package/ai/components/CursorCard.json +128 -0
  33. package/ai/components/DataTooltip.json +15 -0
  34. package/ai/components/DateInput.json +21 -0
  35. package/ai/components/DatePicker.json +143 -0
  36. package/ai/components/DateRangeInput.json +18 -0
  37. package/ai/components/DateRangePicker.json +129 -0
  38. package/ai/components/Dialog.json +134 -0
  39. package/ai/components/DialogProvider.json +8 -0
  40. package/ai/components/Dropdown.json +128 -0
  41. package/ai/components/DropdownWrapper.json +28 -0
  42. package/ai/components/EmojiPicker.json +129 -0
  43. package/ai/components/EmojiPickerDropdown.json +13 -0
  44. package/ai/components/Fade.json +130 -0
  45. package/ai/components/FadingLettersFx.json +77 -0
  46. package/ai/components/Feedback.json +132 -0
  47. package/ai/components/Flex.json +125 -0
  48. package/ai/components/FlipFx.json +133 -0
  49. package/ai/components/GlitchFx.json +128 -0
  50. package/ai/components/Grid.json +121 -0
  51. package/ai/components/Heading.json +75 -0
  52. package/ai/components/HeadingLink.json +127 -0
  53. package/ai/components/HeadingNav.json +124 -0
  54. package/ai/components/HoloFx.json +128 -0
  55. package/ai/components/Hover.json +130 -0
  56. package/ai/components/HoverCard.json +122 -0
  57. package/ai/components/Icon.json +132 -0
  58. package/ai/components/IconButton.json +22 -0
  59. package/ai/components/InfiniteScroll.json +130 -0
  60. package/ai/components/InlineCode.json +126 -0
  61. package/ai/components/Input.json +24 -0
  62. package/ai/components/InteractiveDetails.json +14 -0
  63. package/ai/components/Kbar.json +10 -0
  64. package/ai/components/Kbd.json +127 -0
  65. package/ai/components/Legend.json +14 -0
  66. package/ai/components/LetterFx.json +14 -0
  67. package/ai/components/Line.json +125 -0
  68. package/ai/components/LineBarChart.json +123 -0
  69. package/ai/components/LineChart.json +123 -0
  70. package/ai/components/LinearGauge.json +130 -0
  71. package/ai/components/LinearGradient.json +15 -0
  72. package/ai/components/List.json +127 -0
  73. package/ai/components/ListItem.json +77 -0
  74. package/ai/components/Logo.json +16 -0
  75. package/ai/components/LogoCloud.json +124 -0
  76. package/ai/components/Mask.json +131 -0
  77. package/ai/components/MasonryGrid.json +132 -0
  78. package/ai/components/MatrixFx.json +135 -0
  79. package/ai/components/Media.json +142 -0
  80. package/ai/components/MediaUpload.json +122 -0
  81. package/ai/components/MegaMenu.json +125 -0
  82. package/ai/components/MobileMegaMenu.json +125 -0
  83. package/ai/components/Modal.json +12 -0
  84. package/ai/components/NavIcon.json +127 -0
  85. package/ai/components/NumberInput.json +16 -0
  86. package/ai/components/OTPInput.json +13 -0
  87. package/ai/components/OgCard.json +135 -0
  88. package/ai/components/Option.json +137 -0
  89. package/ai/components/Particle.json +135 -0
  90. package/ai/components/PasswordInput.json +8 -0
  91. package/ai/components/PieChart.json +123 -0
  92. package/ai/components/ProgressBar.json +131 -0
  93. package/ai/components/Pulse.json +129 -0
  94. package/ai/components/RadialGauge.json +134 -0
  95. package/ai/components/RadialGradient.json +16 -0
  96. package/ai/components/RadioButton.json +17 -0
  97. package/ai/components/RevealFx.json +131 -0
  98. package/ai/components/Row.json +128 -0
  99. package/ai/components/Schema.json +17 -0
  100. package/ai/components/ScrollContainer.json +126 -0
  101. package/ai/components/ScrollToTop.json +124 -0
  102. package/ai/components/Scroller.json +128 -0
  103. package/ai/components/SegmentedControl.json +132 -0
  104. package/ai/components/Select.json +21 -0
  105. package/ai/components/ShineFx.json +80 -0
  106. package/ai/components/Skeleton.json +129 -0
  107. package/ai/components/Slider.json +17 -0
  108. package/ai/components/SmartLink.json +17 -0
  109. package/ai/components/Spinner.json +127 -0
  110. package/ai/components/SplitView.json +129 -0
  111. package/ai/components/StatusIndicator.json +128 -0
  112. package/ai/components/StyleOverlay.json +126 -0
  113. package/ai/components/StylePanel.json +125 -0
  114. package/ai/components/Swiper.json +130 -0
  115. package/ai/components/Switch.json +20 -0
  116. package/ai/components/Table.json +125 -0
  117. package/ai/components/Tag.json +129 -0
  118. package/ai/components/TagInput.json +12 -0
  119. package/ai/components/Text.json +72 -0
  120. package/ai/components/Textarea.json +24 -0
  121. package/ai/components/ThemeSwitcher.json +122 -0
  122. package/ai/components/TiltFx.json +126 -0
  123. package/ai/components/Timeline.json +126 -0
  124. package/ai/components/Toast.json +13 -0
  125. package/ai/components/Toaster.json +14 -0
  126. package/ai/components/ToggleButton.json +24 -0
  127. package/ai/components/Tooltip.json +129 -0
  128. package/ai/components/TypeFx.json +15 -0
  129. package/ai/components/User.json +15 -0
  130. package/ai/components/UserMenu.json +16 -0
  131. package/ai/components/WeatherFx.json +133 -0
  132. package/ai/examples/auth.tsx +105 -0
  133. package/ai/examples/blocks/Background6.tsx +25 -0
  134. package/ai/examples/blocks/Chat1.tsx +70 -0
  135. package/ai/examples/blocks/Dashboard1.tsx +404 -0
  136. package/ai/examples/blocks/Feed3.tsx +151 -0
  137. package/ai/examples/blocks/Footer1.tsx +30 -0
  138. package/ai/examples/blocks/Footer2.tsx +96 -0
  139. package/ai/examples/blocks/Footer3.tsx +127 -0
  140. package/ai/examples/blocks/Footer4.tsx +406 -0
  141. package/ai/examples/blocks/Header1.tsx +370 -0
  142. package/ai/examples/blocks/Header2.tsx +98 -0
  143. package/ai/examples/blocks/Header3.tsx +133 -0
  144. package/ai/examples/blocks/Header4.tsx +123 -0
  145. package/ai/examples/blocks/Productivity1.tsx +318 -0
  146. package/ai/examples/blocks/Roadmap1.tsx +133 -0
  147. package/ai/examples/blocks/Sidebar1.tsx +34 -0
  148. package/ai/examples/blocks/Sidebar2.tsx +17 -0
  149. package/ai/examples/blocks/Sidebar4.tsx +92 -0
  150. package/ai/examples/blocks/Sidebar5.tsx +73 -0
  151. package/ai/examples/blocks/Streaming1.tsx +353 -0
  152. package/ai/examples/blocks/Table1.tsx +303 -0
  153. package/ai/examples/blocks/Waitlist1.tsx +141 -0
  154. package/ai/examples/blocks/content/chat1content.ts +65 -0
  155. package/ai/examples/blocks/content/resources.ts +5 -0
  156. package/ai/examples/blocks/content/roadmap1content.ts +51 -0
  157. package/ai/examples/blocks/manifest.json +191 -0
  158. package/ai/examples/dashboard.tsx +150 -0
  159. package/ai/examples/marketing-hero.tsx +152 -0
  160. package/ai/examples/pricing.tsx +219 -0
  161. package/ai/examples/settings.tsx +140 -0
  162. package/ai/gotchas.json +85 -0
  163. package/ai/manifest.json +21 -0
  164. package/ai/rules.compact.md +73 -0
  165. package/ai/spec.json +2679 -2701
  166. package/ai/tasks/auth.json +23 -0
  167. package/ai/tasks/chat.json +28 -0
  168. package/ai/tasks/dashboard.json +39 -0
  169. package/ai/tasks/index.json +12 -0
  170. package/ai/tasks/marketing-hero.json +38 -0
  171. package/ai/tasks/pricing.json +42 -0
  172. package/ai/tasks/roadmap.json +22 -0
  173. package/ai/tasks/settings.json +34 -0
  174. package/dist/ai/catalog.json +1650 -0
  175. package/dist/ai/catalog.seed.json +411 -0
  176. package/dist/ai/components/Accordion.json +136 -0
  177. package/dist/ai/components/AccordionGroup.json +128 -0
  178. package/dist/ai/components/Animation.json +146 -0
  179. package/dist/ai/components/Arrow.json +128 -0
  180. package/dist/ai/components/AutoScroll.json +130 -0
  181. package/dist/ai/components/Avatar.json +133 -0
  182. package/dist/ai/components/AvatarGroup.json +129 -0
  183. package/dist/ai/components/Background.json +131 -0
  184. package/dist/ai/components/Badge.json +132 -0
  185. package/dist/ai/components/Banner.json +122 -0
  186. package/dist/ai/components/BarChart.json +123 -0
  187. package/dist/ai/components/BlobFx.json +125 -0
  188. package/dist/ai/components/BlockQuote.json +132 -0
  189. package/dist/ai/components/Button.json +26 -0
  190. package/dist/ai/components/Card.json +129 -0
  191. package/dist/ai/components/Carousel.json +134 -0
  192. package/dist/ai/components/CelebrationFx.json +132 -0
  193. package/dist/ai/components/ChartHeader.json +130 -0
  194. package/dist/ai/components/ChartStatus.json +12 -0
  195. package/dist/ai/components/Checkbox.json +13 -0
  196. package/dist/ai/components/Chip.json +132 -0
  197. package/dist/ai/components/CodeBlock.json +122 -0
  198. package/dist/ai/components/ColorInput.json +13 -0
  199. package/dist/ai/components/Column.json +128 -0
  200. package/dist/ai/components/CompareImage.json +126 -0
  201. package/dist/ai/components/ContextMenu.json +22 -0
  202. package/dist/ai/components/CountFx.json +82 -0
  203. package/dist/ai/components/CountdownFx.json +11 -0
  204. package/dist/ai/components/Cursor.json +9 -0
  205. package/dist/ai/components/CursorCard.json +128 -0
  206. package/dist/ai/components/DataTooltip.json +15 -0
  207. package/dist/ai/components/DateInput.json +21 -0
  208. package/dist/ai/components/DatePicker.json +143 -0
  209. package/dist/ai/components/DateRangeInput.json +18 -0
  210. package/dist/ai/components/DateRangePicker.json +129 -0
  211. package/dist/ai/components/Dialog.json +134 -0
  212. package/dist/ai/components/DialogProvider.json +8 -0
  213. package/dist/ai/components/Dropdown.json +128 -0
  214. package/dist/ai/components/DropdownWrapper.json +28 -0
  215. package/dist/ai/components/EmojiPicker.json +129 -0
  216. package/dist/ai/components/EmojiPickerDropdown.json +13 -0
  217. package/dist/ai/components/Fade.json +130 -0
  218. package/dist/ai/components/FadingLettersFx.json +77 -0
  219. package/dist/ai/components/Feedback.json +132 -0
  220. package/dist/ai/components/Flex.json +125 -0
  221. package/dist/ai/components/FlipFx.json +133 -0
  222. package/dist/ai/components/GlitchFx.json +128 -0
  223. package/dist/ai/components/Grid.json +121 -0
  224. package/dist/ai/components/Heading.json +75 -0
  225. package/dist/ai/components/HeadingLink.json +127 -0
  226. package/dist/ai/components/HeadingNav.json +124 -0
  227. package/dist/ai/components/HoloFx.json +128 -0
  228. package/dist/ai/components/Hover.json +130 -0
  229. package/dist/ai/components/HoverCard.json +122 -0
  230. package/dist/ai/components/Icon.json +132 -0
  231. package/dist/ai/components/IconButton.json +22 -0
  232. package/dist/ai/components/InfiniteScroll.json +130 -0
  233. package/dist/ai/components/InlineCode.json +126 -0
  234. package/dist/ai/components/Input.json +24 -0
  235. package/dist/ai/components/InteractiveDetails.json +14 -0
  236. package/dist/ai/components/Kbar.json +10 -0
  237. package/dist/ai/components/Kbd.json +127 -0
  238. package/dist/ai/components/Legend.json +14 -0
  239. package/dist/ai/components/LetterFx.json +14 -0
  240. package/dist/ai/components/Line.json +125 -0
  241. package/dist/ai/components/LineBarChart.json +123 -0
  242. package/dist/ai/components/LineChart.json +123 -0
  243. package/dist/ai/components/LinearGauge.json +130 -0
  244. package/dist/ai/components/LinearGradient.json +15 -0
  245. package/dist/ai/components/List.json +127 -0
  246. package/dist/ai/components/ListItem.json +77 -0
  247. package/dist/ai/components/Logo.json +16 -0
  248. package/dist/ai/components/LogoCloud.json +124 -0
  249. package/dist/ai/components/Mask.json +131 -0
  250. package/dist/ai/components/MasonryGrid.json +132 -0
  251. package/dist/ai/components/MatrixFx.json +135 -0
  252. package/dist/ai/components/Media.json +142 -0
  253. package/dist/ai/components/MediaUpload.json +122 -0
  254. package/dist/ai/components/MegaMenu.json +125 -0
  255. package/dist/ai/components/MobileMegaMenu.json +125 -0
  256. package/dist/ai/components/Modal.json +12 -0
  257. package/dist/ai/components/NavIcon.json +127 -0
  258. package/dist/ai/components/NumberInput.json +16 -0
  259. package/dist/ai/components/OTPInput.json +13 -0
  260. package/dist/ai/components/OgCard.json +135 -0
  261. package/dist/ai/components/Option.json +137 -0
  262. package/dist/ai/components/Particle.json +135 -0
  263. package/dist/ai/components/PasswordInput.json +8 -0
  264. package/dist/ai/components/PieChart.json +123 -0
  265. package/dist/ai/components/ProgressBar.json +131 -0
  266. package/dist/ai/components/Pulse.json +129 -0
  267. package/dist/ai/components/RadialGauge.json +134 -0
  268. package/dist/ai/components/RadialGradient.json +16 -0
  269. package/dist/ai/components/RadioButton.json +17 -0
  270. package/dist/ai/components/RevealFx.json +131 -0
  271. package/dist/ai/components/Row.json +128 -0
  272. package/dist/ai/components/Schema.json +17 -0
  273. package/dist/ai/components/ScrollContainer.json +126 -0
  274. package/dist/ai/components/ScrollToTop.json +124 -0
  275. package/dist/ai/components/Scroller.json +128 -0
  276. package/dist/ai/components/SegmentedControl.json +132 -0
  277. package/dist/ai/components/Select.json +21 -0
  278. package/dist/ai/components/ShineFx.json +80 -0
  279. package/dist/ai/components/Skeleton.json +129 -0
  280. package/dist/ai/components/Slider.json +17 -0
  281. package/dist/ai/components/SmartLink.json +17 -0
  282. package/dist/ai/components/Spinner.json +127 -0
  283. package/dist/ai/components/SplitView.json +129 -0
  284. package/dist/ai/components/StatusIndicator.json +128 -0
  285. package/dist/ai/components/StyleOverlay.json +126 -0
  286. package/dist/ai/components/StylePanel.json +125 -0
  287. package/dist/ai/components/Swiper.json +130 -0
  288. package/dist/ai/components/Switch.json +20 -0
  289. package/dist/ai/components/Table.json +125 -0
  290. package/dist/ai/components/Tag.json +129 -0
  291. package/dist/ai/components/TagInput.json +12 -0
  292. package/dist/ai/components/Text.json +72 -0
  293. package/dist/ai/components/Textarea.json +24 -0
  294. package/dist/ai/components/ThemeSwitcher.json +122 -0
  295. package/dist/ai/components/TiltFx.json +126 -0
  296. package/dist/ai/components/Timeline.json +126 -0
  297. package/dist/ai/components/Toast.json +13 -0
  298. package/dist/ai/components/Toaster.json +14 -0
  299. package/dist/ai/components/ToggleButton.json +24 -0
  300. package/dist/ai/components/Tooltip.json +129 -0
  301. package/dist/ai/components/TypeFx.json +15 -0
  302. package/dist/ai/components/User.json +15 -0
  303. package/dist/ai/components/UserMenu.json +16 -0
  304. package/dist/ai/components/WeatherFx.json +133 -0
  305. package/dist/ai/eval-tasks.md +71 -0
  306. package/dist/ai/examples/blocks/manifest.json +191 -0
  307. package/dist/ai/gotchas.json +85 -0
  308. package/dist/ai/manifest.json +21 -0
  309. package/dist/ai/recipes.md +149 -0
  310. package/dist/ai/rules.compact.md +73 -0
  311. package/dist/ai/rules.md +217 -0
  312. package/dist/ai/spec.json +2680 -0
  313. package/dist/ai/tasks/auth.json +23 -0
  314. package/dist/ai/tasks/chat.json +28 -0
  315. package/dist/ai/tasks/dashboard.json +39 -0
  316. package/dist/ai/tasks/index.json +12 -0
  317. package/dist/ai/tasks/marketing-hero.json +38 -0
  318. package/dist/ai/tasks/pricing.json +42 -0
  319. package/dist/ai/tasks/roadmap.json +22 -0
  320. package/dist/ai/tasks/settings.json +34 -0
  321. package/dist/data/emoji-data.json +0 -18
  322. package/dist/package.json +13 -2
  323. package/package.json +139 -127
  324. package/LICENSE.md +0 -21
  325. package/next-env.d.ts +0 -5
@@ -0,0 +1,217 @@
1
+ # Once UI — code generation rules
2
+
3
+ Rules for writing Once UI code. Follow every rule; each shows the correct form first.
4
+
5
+ ## Before you build
6
+
7
+ When the request doesn't specify design intent, ask these five questions first (one short message, all at once), then build:
8
+
9
+ 1. **Content style** — bold / restrained / conservative?
10
+ 2. **Layout** — wide or narrow, centered or left-aligned?
11
+ 3. **Color** — single accent, bold colors, visually distinct sections?
12
+ 4. **Decoration** — gradients, MatrixFx, animated blobs, none?
13
+ 5. **Imagery** — placeholder images, or avatars/logos/icons only?
14
+
15
+ If you can't ask (or the user says "you decide"), default to: restrained, centered with `maxWidth="m"` content, single brand accent, one subtle gradient (recipes.md #1), no placeholder images (use `Avatar`, `Logo`, `Icon`).
16
+
17
+ ## Layout primitives
18
+
19
+ 1. Use `Row` and `Column` for layout. `Flex` with `direction` is only for dynamic direction.
20
+
21
+ ```tsx
22
+ // Good
23
+ <Column gap="16">...</Column>
24
+ // Bad
25
+ <Flex direction="column" gap="16">...</Flex>
26
+ ```
27
+
28
+ 2. Use shorthands — they replace multi-prop combinations:
29
+
30
+ | Write | Instead of |
31
+ |-------|------------|
32
+ | `fill` | `fillWidth fillHeight` |
33
+ | `fit` | `fitWidth fitHeight` |
34
+ | `center` | `horizontal="center" vertical="center"` |
35
+
36
+ ```tsx
37
+ // Good
38
+ <Row fill center>...</Row>
39
+ // Bad
40
+ <Row fillWidth fillHeight horizontal="center" vertical="center">...</Row>
41
+ ```
42
+
43
+ 3. Never write a prop that equals its default. The spec marks defaults with `= value`. Common offenders:
44
+ - `position="relative"` (default on all layout components)
45
+ - `direction="row"` on `Row`, `direction="column"` on `Column`
46
+ - `variant="primary"`, `size="m"` on `Button`
47
+
48
+ ## Spacing and sizing
49
+
50
+ 4. Use spacing tokens, never raw CSS: `gap`, `padding`, `margin`, `paddingX/Y`, `marginX/Y` accept tokens (`"2" "4" "8" "12" "16" "20" "24" "32" "40" "48" "64"` or `"xs" "s" "m" "l" "xl"`).
51
+
52
+ ```tsx
53
+ // Good
54
+ <Column gap="8" padding="24">
55
+ // Bad
56
+ <div style={{ gap: 8, padding: 24 }}>
57
+ ```
58
+
59
+ 5. `width`/`height`/`maxWidth`/`minHeight` accept numbers (rem), tokens, or CSS units. Prefer numbers/tokens.
60
+
61
+ 6. Only use `style={{}}` for things no token prop covers (e.g. `isolation`, custom filters). If a prop exists, the prop wins.
62
+
63
+ ## Color and surfaces
64
+
65
+ 7. Colors are semantic tokens, never hex/rgb: `{scheme}-{weight}` or `{scheme}-alpha-{weight}` where scheme = `neutral | brand | accent | info | danger | warning | success` and weight = `weak | medium | strong`.
66
+ - `background` also accepts `surface | overlay | page | transparent`
67
+ - `onBackground` colors text/icons on a background
68
+
69
+ 8. Standard surface recipe: `background="surface"` (or `"overlay"` over imagery) + `border="neutral-alpha-weak"` (or `-medium`) + `radius="l"`.
70
+
71
+ ```tsx
72
+ <Column background="surface" border="neutral-alpha-weak" radius="l" padding="24" gap="16">
73
+ ```
74
+
75
+ ## Text
76
+
77
+ 9. Use `Text` and `Heading` with `variant="{type}-{weight}-{size}"`: type = `body | heading | display | label | code`, weight = `default | strong`, size = `xs | s | m | l | xl`. Examples: `body-default-m`, `heading-strong-s`, `label-default-s`, `display-strong-m`.
78
+
79
+ 10. If a layout component only wraps text, put `textVariant` (and `onBackground`) directly on it instead of nesting a `Text`:
80
+
81
+ ```tsx
82
+ // Good
83
+ <Row textVariant="label-default-s" onBackground="neutral-weak">Updated today</Row>
84
+ // Bad
85
+ <Row><Text variant="label-default-s" onBackground="neutral-weak">Updated today</Text></Row>
86
+ ```
87
+
88
+ ## Responsive
89
+
90
+ 11. Use breakpoint props (`xl l m s xs`) with override objects — never media queries or conditional rendering for layout:
91
+
92
+ ```tsx
93
+ <Row gap="24" s={{ direction: "column" }}>
94
+ <Grid columns="3" s={{ columns: 1 }}>
95
+ ```
96
+
97
+ ## Components over primitives
98
+
99
+ 12. Reach for the purpose-built component before composing primitives:
100
+ - `Card` is for **interactive** surfaces only (`href` or `onClick`). Static panels (pricing tiers, testimonials, stat boxes) = `Column`/`Row` with the surface recipe (#8), not `Card`
101
+ - Image/video → `Media`, not `img`
102
+ - Links → `SmartLink` / `Button href`, not `a`
103
+ - Status dot → `StatusIndicator`; progress → `ProgressBar`; loading → `Spinner` / `Skeleton`
104
+ - Labels/metadata → `Tag`, `Chip`, `Badge`, `Kbd`, `InlineCode`
105
+
106
+ 13. Use the distinctive features when the design calls for them — they exist and are cheap:
107
+ - `Dialog` supports `stack` (stacked dialogs) and `base` props
108
+ - Effects: `RevealFx`, `LetterFx`, `TypeFx`, `CountFx`, `GlitchFx`, `HoloFx`, `TiltFx`, `FlipFx`, `MatrixFx`, `BlobFx`, `Particle`, `ShineFx`, `CelebrationFx`
109
+ - `CursorCard`, `HoverCard`, `ContextMenu`, `EmojiPicker`, `CompareImage`, `OgCard`, `Timeline`, `MasonryGrid`, `InfiniteScroll`, `SegmentedControl`, `Kbar` (command palette)
110
+ - Forms: `Input`, `PasswordInput`, `OTPInput`, `NumberInput`, `TagInput`, `Select`, `DatePicker`, `DateRangePicker`, `ColorInput`, `Slider`, `Switch`, `Checkbox`, `Chip`
111
+
112
+ 14. Buttons: `variant` = `primary | secondary | tertiary | danger`; pair with `prefixIcon`/`suffixIcon` (icon names, not elements). `IconButton` for icon-only actions with `tooltip`.
113
+
114
+ 14b. Icon names must come from the `IconName` list in spec.json — never invent names (`more`, `bell`, and `arrowRight` don't exist; `close`, `chevronRight`, and `smiley` do). If no icon fits, omit the icon.
115
+
116
+ 14c. Components with a text prop render it — never pass the same text as both prop and children, it renders twice:
117
+
118
+ ```tsx
119
+ // Good
120
+ <Badge>{unread}</Badge> or <Tag size="s">Save 20%</Tag>
121
+ // Bad: renders "2 unread2" / "Save 20%Save 20%"
122
+ <Badge title={`${unread} unread`}>{unread}</Badge>
123
+ <Tag label="Save 20%">Save 20%</Tag>
124
+ ```
125
+
126
+ 14d. `Fade` is an **edge overlay strip** (scroll-fade at the boundary of a scroll container), not a content wrapper. Wrapping a message list or section in `Fade` washes the whole content out:
127
+
128
+ ```tsx
129
+ // Good: thin absolute strip over the scroll edge
130
+ <Column flex={1} overflowY="auto">...</Column>
131
+ <Fade position="absolute" top="0" left="0" fillWidth height="40" to="bottom" base="surface" pointerEvents="none" />
132
+ // Bad
133
+ <Fade to="top" fill><Column overflowY="auto">...</Column></Fade>
134
+ ```
135
+
136
+ ## Composition rhythm
137
+
138
+ 15. Page skeleton: `Column as="main" fillWidth horizontal="center"` → content `Column maxWidth={...}` → sections. Gaps between siblings, padding inside surfaces; avoid margins for layout when a parent `gap` can do it.
139
+
140
+ `maxWidth` conventions: primary page containers `"xl"`–`"m"` (marketing/landing toward `"xl"`/`"l"`, app and docs content `"m"`). `"s"` is only for narrow reading content (about, legal); `"xs"` for special surfaces (drawers, popovers).
141
+
142
+ 16. Data attributes for one-off theme overrides: `data-border="rounded"`, `data-brand="emerald"`, `data-solid="contrast"` — not custom CSS.
143
+
144
+ ## Scale and hierarchy (marketing/landing pages)
145
+
146
+ 17. Vertical rhythm is generous. Gap between page sections: `"80"`–`"160"` (typical `"104"`). Gap inside a section: `"24"`–`"40"`. Spacing tokens go up to `"160"` — use the top of the scale between sections, not `"48"`.
147
+
148
+ 18. Heading scale: hero = `display-strong-l` (or `xl`), section headings = `display-strong-xs` or `display-strong-s` — never `heading-*` variants for section titles. Hero supporting text = `body-default-l`; section supporting text = `body-default-m`.
149
+
150
+ 19. Type hierarchy must be monotonic: quotes, testimonials, and body content never render larger than the section heading above them. Testimonial quotes = `body-default-m` max, not `BlockQuote` default size.
151
+
152
+ 20. Don't repeat the same centered heading + subtitle block for every section — it reads dated. Vary: left-aligned headers, heading-only sections, or an eyebrow label above the heading. Eyebrow = plain text, not a `Tag` with an icon:
153
+
154
+ ```tsx
155
+ // Good eyebrow
156
+ <Text variant="label-default-s" onBackground="brand-medium">Pricing</Text>
157
+ // Bad eyebrow
158
+ <Tag variant="neutral" prefixIcon="sparkle">Pricing</Tag>
159
+ ```
160
+
161
+ ## Decorative layers
162
+
163
+ 21. Every absolute decorative layer uses the full recipe — `top="0" left="0"` are required or the layer gets offset by parent padding:
164
+
165
+ ```tsx
166
+ <Background position="absolute" top="0" left="0" fill pointerEvents="none" ... />
167
+ ```
168
+
169
+ Siblings holding content get `zIndex={1}`. `overflow="hidden"` goes on the parent **only when it has a radius** (cards, panels) — clipping a full-bleed section turns the glow into a hard-edged band.
170
+
171
+ 21b. Ambient section layers (hero glows) live on the **full-width section wrapper**, outside the `maxWidth` content column, with generous room (`paddingY="80"`+). Inside a narrow container the gradient gets clipped at the container edge and reads as a misplaced card:
172
+
173
+ ```tsx
174
+ // Good: full-bleed section, narrow content inside
175
+ <Column fillWidth horizontal="center" paddingY="80">
176
+ <Background position="absolute" top="0" left="0" fill pointerEvents="none" gradient={{...}} />
177
+ <Column zIndex={1} maxWidth={48}>...</Column>
178
+ </Column>
179
+ ```
180
+
181
+ 22. `Background` gradient units: `x`/`y` are percent positions of the container (50/50 = center). `width`/`height` are quarter-percent units: `400` = 100% of the container, `100` = 25%. A soft corner glow is `width: 100–200`; `width: 500` overshoots the container.
182
+
183
+ 23. Color visibility: `*-background-weak` is nearly the page color — it is invisible as an accent. For tints and glows use alpha tokens (`brand-alpha-medium`, `brand-alpha-strong`) or solid tokens (`brand-solid-strong`) and do not stack a low `opacity` on top of an already-weak color.
184
+
185
+ ## Effect units
186
+
187
+ 24. `RevealFx`: `delay` is in **seconds** — stagger with `delay={index * 0.1}`, never `index * 80`. `translateY` as a number is in **rem** — use `translateY={1}` or a token like `"16"` (1rem); `16` means 16rem.
188
+
189
+ 25. `LogoCloud` extends `Grid` — always set `columns` (and responsive overrides), or logos stack in one column: `columns="4" m={{ columns: 3 }} s={{ columns: 2 }}`.
190
+
191
+ 26. Use decoration recipes from `recipes.md` verbatim, then adjust. Budget: at most one ambient background layer per section, ambient motion in at most the hero and final CTA, one accent color family per page.
192
+
193
+ ## Motion
194
+
195
+ 27. Animations are **eye-leading, not eye-grabbing**: they direct attention to the one thing that should be read next, they don't announce themselves. Small distances (`translateY="8"`–`"16"`, i.e. 0.5–1rem), short staggers (`delay={index * 0.1}` max), and only on elements worth leading the eye to — the hero heading, stat numbers, the highlighted card in a set.
196
+
197
+ 28. Do **not** wrap every section in `RevealFx` — uniform entrance animation on everything reads dated and makes scrolling feel slow. Entry-animation budget per page: the hero, plus at most one or two key moments (stats, a card set). Everything else just renders.
198
+
199
+ 28b. Animate **coherent blocks, all-or-none**. Within a sibling set (cards, list items), either every sibling animates with a stagger or none do — never a single item out of the set (e.g. only the highlighted pricing card). For a hero, reveal it as 1–3 stacked chunks with increasing delay (`0 / 0.1 / 0.2`), not individual text fragments. One entrance moment per viewport: if the hero animates, the cards below it don't.
200
+
201
+ 29. Trigger below-the-fold animations with `useInViewport`, latched so they play once. `RevealFx` takes `trigger`; `CountFx` has no trigger prop — drive its `value` instead:
202
+
203
+ ```tsx
204
+ const ref = useRef<HTMLDivElement>(null);
205
+ const inViewport = useInViewport(ref);
206
+ const [seen, setSeen] = useState(false);
207
+ useEffect(() => {
208
+ if (inViewport) setSeen(true); // latch: useInViewport flips back to false on scroll-out
209
+ }, [inViewport]);
210
+
211
+ <Column ref={ref} gap="16">
212
+ <RevealFx trigger={seen} translateY="8">...</RevealFx>
213
+ <CountFx value={seen ? 2400 : 0} speed={1500} separator="," variant="display-strong-m" />
214
+ </Column>
215
+ ```
216
+
217
+ Without this, mount-timed animations play while still off-screen and the user scrolls into an already-finished state.