@once-ui-system/core 1.8.3 → 2.0.0-alpha.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 (577) hide show
  1. package/ai/catalog.json +166 -78
  2. package/ai/components/Accordion.json +1 -1
  3. package/ai/components/BarChart.json +34 -3
  4. package/ai/components/Book.json +128 -0
  5. package/ai/components/Button.json +1 -1
  6. package/ai/components/Card.json +1 -0
  7. package/ai/components/Carousel.json +1 -1
  8. package/ai/components/ChartHeader.json +2 -1
  9. package/ai/components/ChartStatus.json +2 -1
  10. package/ai/components/Checkbox.json +2 -2
  11. package/ai/components/CodeBlock.json +23 -2
  12. package/ai/components/ColorInput.json +1 -1
  13. package/ai/components/DataTooltip.json +3 -2
  14. package/ai/components/DatePicker.json +2 -2
  15. package/ai/components/Dialog.json +1 -1
  16. package/ai/components/DropdownWrapper.json +6 -4
  17. package/ai/components/Effect.json +133 -0
  18. package/ai/components/Fade.json +1 -1
  19. package/ai/components/Feedback.json +1 -1
  20. package/ai/components/IconButton.json +1 -1
  21. package/ai/components/InfoTip.json +125 -0
  22. package/ai/components/Input.json +5 -4
  23. package/ai/components/Legend.json +2 -1
  24. package/ai/components/LineBarChart.json +34 -3
  25. package/ai/components/LineChart.json +39 -3
  26. package/ai/components/LinearGauge.json +3 -2
  27. package/ai/components/LinearGradient.json +2 -1
  28. package/ai/components/Logo.json +2 -2
  29. package/ai/components/Media.json +1 -1
  30. package/ai/components/MediaUpload.json +21 -2
  31. package/ai/components/Modal.json +1 -1
  32. package/ai/components/NavGroup.json +130 -0
  33. package/ai/components/NavIcon.json +1 -1
  34. package/ai/components/NavItem.json +14 -0
  35. package/ai/components/Option.json +2 -2
  36. package/ai/components/Particle.json +1 -1
  37. package/ai/components/PieChart.json +32 -3
  38. package/ai/components/ProgressBar.json +1 -1
  39. package/ai/components/Pulse.json +1 -1
  40. package/ai/components/RadialGauge.json +4 -3
  41. package/ai/components/RadialGradient.json +2 -1
  42. package/ai/components/RadioButton.json +1 -1
  43. package/ai/components/RevealFx.json +1 -1
  44. package/ai/components/Scrubber.json +136 -0
  45. package/ai/components/SegmentedControl.json +3 -3
  46. package/ai/components/Setting.json +128 -0
  47. package/ai/components/SettingAxes.json +127 -0
  48. package/ai/components/SettingGroup.json +129 -0
  49. package/ai/components/ShineFx.json +1 -1
  50. package/ai/components/Skeleton.json +2 -3
  51. package/ai/components/SplitView.json +2 -0
  52. package/ai/components/StylePanel.json +4 -2
  53. package/ai/components/Swatch.json +11 -0
  54. package/ai/components/Swiper.json +1 -1
  55. package/ai/components/Switch.json +1 -1
  56. package/ai/components/Tag.json +1 -1
  57. package/ai/components/Textarea.json +6 -5
  58. package/ai/components/ThemeSwitcher.json +3 -0
  59. package/ai/components/Toast.json +1 -1
  60. package/ai/components/ToggleButton.json +2 -1
  61. package/ai/eval-tasks.md +8 -0
  62. package/ai/examples/app-shell.tsx +111 -0
  63. package/ai/examples/auth.tsx +1 -1
  64. package/ai/examples/blocks/Dashboard1.tsx +17 -28
  65. package/ai/examples/blocks/Feed3.tsx +4 -4
  66. package/ai/examples/blocks/Footer1.tsx +5 -3
  67. package/ai/examples/blocks/Footer2.tsx +3 -3
  68. package/ai/examples/blocks/Footer3.tsx +1 -1
  69. package/ai/examples/blocks/Footer4.tsx +6 -5
  70. package/ai/examples/blocks/Header1.tsx +7 -6
  71. package/ai/examples/blocks/Header3.tsx +7 -7
  72. package/ai/examples/blocks/Header4.tsx +5 -5
  73. package/ai/examples/blocks/Sidebar4.tsx +1 -1
  74. package/ai/examples/blocks/Streaming1.tsx +4 -4
  75. package/ai/examples/blocks/Table1.tsx +6 -6
  76. package/ai/examples/blocks/Waitlist1.tsx +5 -5
  77. package/ai/examples/blocks/content/resources.ts +3 -1
  78. package/ai/examples/dashboard.tsx +8 -9
  79. package/ai/examples/marketing-hero.tsx +2 -2
  80. package/ai/examples/pricing.tsx +4 -5
  81. package/ai/examples/settings.tsx +3 -3
  82. package/ai/gotchas.json +80 -23
  83. package/ai/layouts.md +154 -0
  84. package/ai/manifest.json +3 -2
  85. package/ai/recipes.md +49 -4
  86. package/ai/rules.compact.md +18 -3
  87. package/ai/rules.md +68 -10
  88. package/ai/spec.json +634 -176
  89. package/dist/ai/catalog.json +166 -78
  90. package/dist/ai/components/Accordion.json +1 -1
  91. package/dist/ai/components/BarChart.json +34 -3
  92. package/dist/ai/components/Book.json +128 -0
  93. package/dist/ai/components/Button.json +1 -1
  94. package/dist/ai/components/Card.json +1 -0
  95. package/dist/ai/components/Carousel.json +1 -1
  96. package/dist/ai/components/ChartHeader.json +2 -1
  97. package/dist/ai/components/ChartStatus.json +2 -1
  98. package/dist/ai/components/Checkbox.json +2 -2
  99. package/dist/ai/components/CodeBlock.json +23 -2
  100. package/dist/ai/components/ColorInput.json +1 -1
  101. package/dist/ai/components/DataTooltip.json +3 -2
  102. package/dist/ai/components/DatePicker.json +2 -2
  103. package/dist/ai/components/Dialog.json +1 -1
  104. package/dist/ai/components/DropdownWrapper.json +6 -4
  105. package/dist/ai/components/Effect.json +133 -0
  106. package/dist/ai/components/Fade.json +1 -1
  107. package/dist/ai/components/Feedback.json +1 -1
  108. package/dist/ai/components/IconButton.json +1 -1
  109. package/dist/ai/components/InfoTip.json +125 -0
  110. package/dist/ai/components/Input.json +5 -4
  111. package/dist/ai/components/Legend.json +2 -1
  112. package/dist/ai/components/LineBarChart.json +34 -3
  113. package/dist/ai/components/LineChart.json +39 -3
  114. package/dist/ai/components/LinearGauge.json +3 -2
  115. package/dist/ai/components/LinearGradient.json +2 -1
  116. package/dist/ai/components/Logo.json +2 -2
  117. package/dist/ai/components/Media.json +1 -1
  118. package/dist/ai/components/MediaUpload.json +21 -2
  119. package/dist/ai/components/Modal.json +1 -1
  120. package/dist/ai/components/NavGroup.json +130 -0
  121. package/dist/ai/components/NavIcon.json +1 -1
  122. package/dist/ai/components/NavItem.json +14 -0
  123. package/dist/ai/components/Option.json +2 -2
  124. package/dist/ai/components/Particle.json +1 -1
  125. package/dist/ai/components/PieChart.json +32 -3
  126. package/dist/ai/components/ProgressBar.json +1 -1
  127. package/dist/ai/components/Pulse.json +1 -1
  128. package/dist/ai/components/RadialGauge.json +4 -3
  129. package/dist/ai/components/RadialGradient.json +2 -1
  130. package/dist/ai/components/RadioButton.json +1 -1
  131. package/dist/ai/components/RevealFx.json +1 -1
  132. package/dist/ai/components/Scrubber.json +136 -0
  133. package/dist/ai/components/SegmentedControl.json +3 -3
  134. package/dist/ai/components/Setting.json +128 -0
  135. package/dist/ai/components/SettingAxes.json +127 -0
  136. package/dist/ai/components/SettingGroup.json +129 -0
  137. package/dist/ai/components/ShineFx.json +1 -1
  138. package/dist/ai/components/Skeleton.json +2 -3
  139. package/dist/ai/components/SplitView.json +2 -0
  140. package/dist/ai/components/StylePanel.json +4 -2
  141. package/dist/ai/components/Swatch.json +11 -0
  142. package/dist/ai/components/Swiper.json +1 -1
  143. package/dist/ai/components/Switch.json +1 -1
  144. package/dist/ai/components/Tag.json +1 -1
  145. package/dist/ai/components/Textarea.json +6 -5
  146. package/dist/ai/components/ThemeSwitcher.json +3 -0
  147. package/dist/ai/components/Toast.json +1 -1
  148. package/dist/ai/components/ToggleButton.json +2 -1
  149. package/dist/ai/eval-tasks.md +8 -0
  150. package/dist/ai/gotchas.json +80 -23
  151. package/dist/ai/layouts.md +154 -0
  152. package/dist/ai/manifest.json +3 -2
  153. package/dist/ai/recipes.md +49 -4
  154. package/dist/ai/rules.compact.md +18 -3
  155. package/dist/ai/rules.md +68 -10
  156. package/dist/ai/spec.json +634 -176
  157. package/dist/components/Accordion.d.ts +2 -1
  158. package/dist/components/Accordion.d.ts.map +1 -1
  159. package/dist/components/Accordion.js.map +1 -1
  160. package/dist/components/Avatar.js +1 -1
  161. package/dist/components/Avatar.js.map +1 -1
  162. package/dist/components/Background.d.ts +6 -6
  163. package/dist/components/Background.d.ts.map +1 -1
  164. package/dist/components/Book.d.ts +28 -0
  165. package/dist/components/Book.d.ts.map +1 -0
  166. package/dist/components/Book.js +24 -0
  167. package/dist/components/Book.js.map +1 -0
  168. package/dist/components/Book.module.scss +45 -0
  169. package/dist/components/Button.d.ts +1 -1
  170. package/dist/components/Button.d.ts.map +1 -1
  171. package/dist/components/Button.js +4 -4
  172. package/dist/components/Button.js.map +1 -1
  173. package/dist/components/Card.d.ts +8 -0
  174. package/dist/components/Card.d.ts.map +1 -1
  175. package/dist/components/Card.js +10 -2
  176. package/dist/components/Card.js.map +1 -1
  177. package/dist/components/Card.module.scss +11 -1
  178. package/dist/components/Carousel.d.ts +7 -1
  179. package/dist/components/Carousel.d.ts.map +1 -1
  180. package/dist/components/Carousel.js +7 -7
  181. package/dist/components/Carousel.js.map +1 -1
  182. package/dist/components/Carousel.module.scss +1 -8
  183. package/dist/components/Checkbox.d.ts +3 -3
  184. package/dist/components/Checkbox.d.ts.map +1 -1
  185. package/dist/components/Checkbox.js +5 -5
  186. package/dist/components/Checkbox.js.map +1 -1
  187. package/dist/components/ClientFlex.d.ts.map +1 -1
  188. package/dist/components/ClientFlex.js +5 -10
  189. package/dist/components/ClientFlex.js.map +1 -1
  190. package/dist/components/ClientGrid.d.ts.map +1 -1
  191. package/dist/components/ClientGrid.js +2 -7
  192. package/dist/components/ClientGrid.js.map +1 -1
  193. package/dist/components/ColorInput.d.ts +1 -1
  194. package/dist/components/ColorInput.d.ts.map +1 -1
  195. package/dist/components/ColorInput.js +7 -13
  196. package/dist/components/ColorInput.js.map +1 -1
  197. package/dist/components/CompareImage.d.ts +1 -1
  198. package/dist/components/CompareImage.d.ts.map +1 -1
  199. package/dist/components/CompareImage.js +2 -2
  200. package/dist/components/CompareImage.js.map +1 -1
  201. package/dist/components/DateInput.d.ts.map +1 -1
  202. package/dist/components/DateInput.js +10 -1
  203. package/dist/components/DateInput.js.map +1 -1
  204. package/dist/components/DatePicker.d.ts +2 -2
  205. package/dist/components/DatePicker.d.ts.map +1 -1
  206. package/dist/components/DatePicker.js +21 -14
  207. package/dist/components/DatePicker.js.map +1 -1
  208. package/dist/components/DateRangeInput.js +3 -3
  209. package/dist/components/DateRangeInput.js.map +1 -1
  210. package/dist/components/Dialog.d.ts +1 -1
  211. package/dist/components/Dialog.d.ts.map +1 -1
  212. package/dist/components/Dialog.js +14 -14
  213. package/dist/components/Dialog.js.map +1 -1
  214. package/dist/components/DropdownWrapper.d.ts +8 -3
  215. package/dist/components/DropdownWrapper.d.ts.map +1 -1
  216. package/dist/components/DropdownWrapper.js +17 -6
  217. package/dist/components/DropdownWrapper.js.map +1 -1
  218. package/dist/components/Effect.d.ts +41 -0
  219. package/dist/components/Effect.d.ts.map +1 -0
  220. package/dist/components/Effect.js +30 -0
  221. package/dist/components/Effect.js.map +1 -0
  222. package/dist/components/ElementType.d.ts +2 -1
  223. package/dist/components/ElementType.d.ts.map +1 -1
  224. package/dist/components/ElementType.js +4 -2
  225. package/dist/components/ElementType.js.map +1 -1
  226. package/dist/components/EmojiPicker.d.ts +1 -1
  227. package/dist/components/EmojiPicker.d.ts.map +1 -1
  228. package/dist/components/EmojiPicker.js +1 -1
  229. package/dist/components/EmojiPicker.js.map +1 -1
  230. package/dist/components/FadingLettersFx.d.ts +1 -1
  231. package/dist/components/FadingLettersFx.d.ts.map +1 -1
  232. package/dist/components/Feedback.d.ts +1 -1
  233. package/dist/components/Feedback.d.ts.map +1 -1
  234. package/dist/components/Feedback.js +2 -2
  235. package/dist/components/Feedback.js.map +1 -1
  236. package/dist/components/Flex.d.ts.map +1 -1
  237. package/dist/components/Flex.js +46 -5
  238. package/dist/components/Flex.js.map +1 -1
  239. package/dist/components/Heading.d.ts +1 -1
  240. package/dist/components/Icon.d.ts.map +1 -1
  241. package/dist/components/Icon.js.map +1 -1
  242. package/dist/components/IconButton.d.ts +1 -1
  243. package/dist/components/IconButton.d.ts.map +1 -1
  244. package/dist/components/IconButton.js +4 -4
  245. package/dist/components/IconButton.js.map +1 -1
  246. package/dist/components/InfiniteScroll.d.ts +1 -1
  247. package/dist/components/InfiniteScroll.d.ts.map +1 -1
  248. package/dist/components/InfoTip.d.ts +17 -0
  249. package/dist/components/InfoTip.d.ts.map +1 -0
  250. package/dist/components/InfoTip.js +12 -0
  251. package/dist/components/InfoTip.js.map +1 -0
  252. package/dist/components/Input.d.ts +11 -5
  253. package/dist/components/Input.d.ts.map +1 -1
  254. package/dist/components/Input.js +32 -16
  255. package/dist/components/Input.js.map +1 -1
  256. package/dist/components/Input.module.scss +313 -1
  257. package/dist/components/InteractiveDetails.d.ts.map +1 -1
  258. package/dist/components/InteractiveDetails.js +1 -1
  259. package/dist/components/InteractiveDetails.js.map +1 -1
  260. package/dist/components/Kbd.d.ts.map +1 -1
  261. package/dist/components/Kbd.js +4 -1
  262. package/dist/components/Kbd.js.map +1 -1
  263. package/dist/components/Logo.d.ts +16 -4
  264. package/dist/components/Logo.d.ts.map +1 -1
  265. package/dist/components/Logo.js +32 -14
  266. package/dist/components/Logo.js.map +1 -1
  267. package/dist/components/Media.d.ts +9 -2
  268. package/dist/components/Media.d.ts.map +1 -1
  269. package/dist/components/Media.js +25 -16
  270. package/dist/components/Media.js.map +1 -1
  271. package/dist/components/MediaAudioPlayer.d.ts +29 -0
  272. package/dist/components/MediaAudioPlayer.d.ts.map +1 -0
  273. package/dist/components/MediaAudioPlayer.js +115 -0
  274. package/dist/components/MediaAudioPlayer.js.map +1 -0
  275. package/dist/components/MediaAudioPlayer.module.scss +38 -0
  276. package/dist/components/Modal.d.ts +1 -1
  277. package/dist/components/Modal.d.ts.map +1 -1
  278. package/dist/components/Modal.js +10 -10
  279. package/dist/components/Modal.js.map +1 -1
  280. package/dist/components/NavGroup.d.ts +33 -0
  281. package/dist/components/NavGroup.d.ts.map +1 -0
  282. package/dist/components/NavGroup.js +27 -0
  283. package/dist/components/NavGroup.js.map +1 -0
  284. package/dist/components/NavIcon.d.ts +1 -1
  285. package/dist/components/NavIcon.d.ts.map +1 -1
  286. package/dist/components/NavIcon.js +2 -2
  287. package/dist/components/NavIcon.js.map +1 -1
  288. package/dist/components/NavItem.d.ts +24 -0
  289. package/dist/components/NavItem.d.ts.map +1 -0
  290. package/dist/components/NavItem.js +18 -0
  291. package/dist/components/NavItem.js.map +1 -0
  292. package/dist/components/NumberInput.js +1 -1
  293. package/dist/components/NumberInput.js.map +1 -1
  294. package/dist/components/OgCard.d.ts +1 -1
  295. package/dist/components/OgCard.js +3 -3
  296. package/dist/components/OgCard.js.map +1 -1
  297. package/dist/components/Option.d.ts +3 -3
  298. package/dist/components/Option.d.ts.map +1 -1
  299. package/dist/components/Option.js +2 -2
  300. package/dist/components/Option.js.map +1 -1
  301. package/dist/components/Particle.d.ts +2 -2
  302. package/dist/components/Particle.d.ts.map +1 -1
  303. package/dist/components/PasswordInput.d.ts.map +1 -1
  304. package/dist/components/PasswordInput.js +2 -2
  305. package/dist/components/PasswordInput.js.map +1 -1
  306. package/dist/components/ProgressBar.d.ts +1 -1
  307. package/dist/components/ProgressBar.d.ts.map +1 -1
  308. package/dist/components/ProgressBar.js +2 -2
  309. package/dist/components/ProgressBar.js.map +1 -1
  310. package/dist/components/Pulse.d.ts +1 -1
  311. package/dist/components/Pulse.d.ts.map +1 -1
  312. package/dist/components/Pulse.js +2 -2
  313. package/dist/components/Pulse.js.map +1 -1
  314. package/dist/components/RadioButton.d.ts +2 -2
  315. package/dist/components/RadioButton.d.ts.map +1 -1
  316. package/dist/components/RadioButton.js +1 -1
  317. package/dist/components/RadioButton.js.map +1 -1
  318. package/dist/components/RevealFx.d.ts +2 -1
  319. package/dist/components/RevealFx.d.ts.map +1 -1
  320. package/dist/components/RevealFx.js +8 -8
  321. package/dist/components/RevealFx.js.map +1 -1
  322. package/dist/components/ScrollContainer.d.ts.map +1 -1
  323. package/dist/components/ScrollContainer.js +1 -1
  324. package/dist/components/ScrollContainer.js.map +1 -1
  325. package/dist/components/ScrollToTop.d.ts +1 -1
  326. package/dist/components/Scrubber.d.ts +70 -0
  327. package/dist/components/Scrubber.d.ts.map +1 -0
  328. package/dist/components/Scrubber.js +161 -0
  329. package/dist/components/Scrubber.js.map +1 -0
  330. package/dist/components/SegmentedControl.d.ts +4 -4
  331. package/dist/components/SegmentedControl.d.ts.map +1 -1
  332. package/dist/components/SegmentedControl.js +11 -11
  333. package/dist/components/SegmentedControl.js.map +1 -1
  334. package/dist/components/Select.d.ts.map +1 -1
  335. package/dist/components/Select.js +48 -15
  336. package/dist/components/Select.js.map +1 -1
  337. package/dist/components/ServerFlex.d.ts +0 -1
  338. package/dist/components/ServerFlex.d.ts.map +1 -1
  339. package/dist/components/ServerFlex.js +99 -52
  340. package/dist/components/ServerFlex.js.map +1 -1
  341. package/dist/components/ServerGrid.d.ts +0 -1
  342. package/dist/components/ServerGrid.d.ts.map +1 -1
  343. package/dist/components/ServerGrid.js +11 -9
  344. package/dist/components/ServerGrid.js.map +1 -1
  345. package/dist/components/Setting.d.ts +50 -0
  346. package/dist/components/Setting.d.ts.map +1 -0
  347. package/dist/components/Setting.js +43 -0
  348. package/dist/components/Setting.js.map +1 -0
  349. package/dist/components/ShineFx.d.ts +1 -0
  350. package/dist/components/ShineFx.d.ts.map +1 -1
  351. package/dist/components/ShineFx.js +2 -2
  352. package/dist/components/ShineFx.js.map +1 -1
  353. package/dist/components/Skeleton.d.ts +16 -3
  354. package/dist/components/Skeleton.d.ts.map +1 -1
  355. package/dist/components/Skeleton.js +2 -2
  356. package/dist/components/Skeleton.js.map +1 -1
  357. package/dist/components/Skeleton.module.scss +14 -51
  358. package/dist/components/SplitView.d.ts +23 -3
  359. package/dist/components/SplitView.d.ts.map +1 -1
  360. package/dist/components/SplitView.js +90 -58
  361. package/dist/components/SplitView.js.map +1 -1
  362. package/dist/components/StyleOverlay.d.ts.map +1 -1
  363. package/dist/components/StyleOverlay.js +1 -1
  364. package/dist/components/StyleOverlay.js.map +1 -1
  365. package/dist/components/StylePanel.d.ts +47 -6
  366. package/dist/components/StylePanel.d.ts.map +1 -1
  367. package/dist/components/StylePanel.js +16 -189
  368. package/dist/components/StylePanel.js.map +1 -1
  369. package/dist/components/StylePanel.module.scss +6 -1
  370. package/dist/components/StylePanelSections.d.ts +117 -0
  371. package/dist/components/StylePanelSections.d.ts.map +1 -0
  372. package/dist/components/StylePanelSections.js +175 -0
  373. package/dist/components/StylePanelSections.js.map +1 -0
  374. package/dist/components/Swiper.d.ts +7 -1
  375. package/dist/components/Swiper.d.ts.map +1 -1
  376. package/dist/components/Swiper.js +7 -7
  377. package/dist/components/Swiper.js.map +1 -1
  378. package/dist/components/Switch.d.ts +2 -2
  379. package/dist/components/Switch.d.ts.map +1 -1
  380. package/dist/components/Switch.js +4 -4
  381. package/dist/components/Switch.js.map +1 -1
  382. package/dist/components/Table.d.ts +1 -1
  383. package/dist/components/Table.d.ts.map +1 -1
  384. package/dist/components/Table.js +2 -2
  385. package/dist/components/Table.js.map +1 -1
  386. package/dist/components/Tag.d.ts +1 -1
  387. package/dist/components/Tag.d.ts.map +1 -1
  388. package/dist/components/Tag.js +2 -2
  389. package/dist/components/Tag.js.map +1 -1
  390. package/dist/components/Text.d.ts +1 -1
  391. package/dist/components/Textarea.d.ts +15 -5
  392. package/dist/components/Textarea.d.ts.map +1 -1
  393. package/dist/components/Textarea.js +31 -17
  394. package/dist/components/Textarea.js.map +1 -1
  395. package/dist/components/ThemeInit.d.ts.map +1 -1
  396. package/dist/components/ThemeInit.js +6 -4
  397. package/dist/components/ThemeInit.js.map +1 -1
  398. package/dist/components/ThemeSwitcher.d.ts +14 -1
  399. package/dist/components/ThemeSwitcher.d.ts.map +1 -1
  400. package/dist/components/ThemeSwitcher.js +19 -9
  401. package/dist/components/ThemeSwitcher.js.map +1 -1
  402. package/dist/components/ThemeSwitcher.module.scss +54 -0
  403. package/dist/components/Toast.d.ts +1 -1
  404. package/dist/components/Toast.d.ts.map +1 -1
  405. package/dist/components/Toast.js +2 -2
  406. package/dist/components/Toast.js.map +1 -1
  407. package/dist/components/ToggleButton.d.ts +9 -2
  408. package/dist/components/ToggleButton.d.ts.map +1 -1
  409. package/dist/components/ToggleButton.js +5 -5
  410. package/dist/components/ToggleButton.js.map +1 -1
  411. package/dist/components/User.js +1 -1
  412. package/dist/components/User.js.map +1 -1
  413. package/dist/components/index.d.ts +7 -0
  414. package/dist/components/index.d.ts.map +1 -1
  415. package/dist/components/index.js +7 -0
  416. package/dist/components/index.js.map +1 -1
  417. package/dist/contexts/AdapterProvider.d.ts +50 -0
  418. package/dist/contexts/AdapterProvider.d.ts.map +1 -0
  419. package/dist/contexts/AdapterProvider.js +91 -0
  420. package/dist/contexts/AdapterProvider.js.map +1 -0
  421. package/dist/contexts/DataThemeProvider.d.ts +1 -1
  422. package/dist/contexts/DataThemeProvider.d.ts.map +1 -1
  423. package/dist/contexts/IconProvider.d.ts +3 -3
  424. package/dist/contexts/IconProvider.d.ts.map +1 -1
  425. package/dist/contexts/IconProvider.js +2 -2
  426. package/dist/contexts/IconProvider.js.map +1 -1
  427. package/dist/contexts/LayoutProvider.d.ts +0 -2
  428. package/dist/contexts/LayoutProvider.d.ts.map +1 -1
  429. package/dist/contexts/LayoutProvider.js +15 -10
  430. package/dist/contexts/LayoutProvider.js.map +1 -1
  431. package/dist/contexts/ThemeProvider.d.ts +29 -1
  432. package/dist/contexts/ThemeProvider.d.ts.map +1 -1
  433. package/dist/contexts/ThemeProvider.js +42 -15
  434. package/dist/contexts/ThemeProvider.js.map +1 -1
  435. package/dist/contexts/index.d.ts +3 -2
  436. package/dist/contexts/index.d.ts.map +1 -1
  437. package/dist/contexts/index.js +3 -2
  438. package/dist/contexts/index.js.map +1 -1
  439. package/dist/css/styles.css +1 -1
  440. package/dist/css/tokens.css +1 -1
  441. package/dist/data/emoji-data.json +0 -10
  442. package/dist/hooks/index.d.ts +0 -1
  443. package/dist/hooks/index.d.ts.map +1 -1
  444. package/dist/hooks/index.js +0 -1
  445. package/dist/hooks/index.js.map +1 -1
  446. package/dist/icons/ATTRIBUTION.md +19 -0
  447. package/dist/icons/data.d.ts +1919 -0
  448. package/dist/icons/data.d.ts.map +1 -0
  449. package/dist/icons/data.js +102 -0
  450. package/dist/icons/data.js.map +1 -0
  451. package/dist/icons/renderIcon.d.ts +26 -0
  452. package/dist/icons/renderIcon.d.ts.map +1 -0
  453. package/dist/icons/renderIcon.js +22 -0
  454. package/dist/icons/renderIcon.js.map +1 -0
  455. package/dist/icons.d.ts +35 -4
  456. package/dist/icons.d.ts.map +1 -1
  457. package/dist/icons.js +13 -60
  458. package/dist/icons.js.map +1 -1
  459. package/dist/modules/code/CodeBlock.impl.d.ts +2 -1
  460. package/dist/modules/code/CodeBlock.impl.d.ts.map +1 -1
  461. package/dist/modules/code/CodeBlock.impl.js +7 -2
  462. package/dist/modules/code/CodeBlock.impl.js.map +1 -1
  463. package/dist/modules/data/ChartHeader.d.ts.map +1 -1
  464. package/dist/modules/data/ChartHeader.js +1 -1
  465. package/dist/modules/data/ChartHeader.js.map +1 -1
  466. package/dist/modules/data/DataTooltip.d.ts +1 -1
  467. package/dist/modules/data/DataTooltip.d.ts.map +1 -1
  468. package/dist/modules/data/DataTooltip.js +2 -2
  469. package/dist/modules/data/DataTooltip.js.map +1 -1
  470. package/dist/modules/data/LinearGauge.d.ts +4 -3
  471. package/dist/modules/data/LinearGauge.d.ts.map +1 -1
  472. package/dist/modules/data/LinearGauge.js +1 -1
  473. package/dist/modules/data/LinearGauge.js.map +1 -1
  474. package/dist/modules/data/PieChart.impl.d.ts +1 -1
  475. package/dist/modules/data/PieChart.impl.d.ts.map +1 -1
  476. package/dist/modules/data/PieChart.impl.js +4 -1
  477. package/dist/modules/data/PieChart.impl.js.map +1 -1
  478. package/dist/modules/data/RadialGauge.d.ts +4 -3
  479. package/dist/modules/data/RadialGauge.d.ts.map +1 -1
  480. package/dist/modules/data/RadialGauge.js +1 -1
  481. package/dist/modules/data/RadialGauge.js.map +1 -1
  482. package/dist/modules/data/interfaces.d.ts +12 -3
  483. package/dist/modules/data/interfaces.d.ts.map +1 -1
  484. package/dist/modules/index.d.ts +1 -4
  485. package/dist/modules/index.d.ts.map +1 -1
  486. package/dist/modules/index.js +9 -3
  487. package/dist/modules/index.js.map +1 -1
  488. package/dist/modules/media/MediaUpload.impl.d.ts +1 -1
  489. package/dist/modules/media/MediaUpload.impl.d.ts.map +1 -1
  490. package/dist/modules/media/MediaUpload.impl.js +1 -1
  491. package/dist/modules/media/MediaUpload.impl.js.map +1 -1
  492. package/dist/modules/navigation/Kbar.d.ts +5 -4
  493. package/dist/modules/navigation/Kbar.d.ts.map +1 -1
  494. package/dist/modules/navigation/Kbar.js +32 -35
  495. package/dist/modules/navigation/Kbar.js.map +1 -1
  496. package/dist/modules/navigation/MegaMenu.d.ts +5 -3
  497. package/dist/modules/navigation/MegaMenu.d.ts.map +1 -1
  498. package/dist/modules/navigation/MegaMenu.js +24 -12
  499. package/dist/modules/navigation/MegaMenu.js.map +1 -1
  500. package/dist/modules/navigation/MobileMegaMenu.d.ts +3 -2
  501. package/dist/modules/navigation/MobileMegaMenu.d.ts.map +1 -1
  502. package/dist/modules/navigation/MobileMegaMenu.js +1 -1
  503. package/dist/modules/navigation/MobileMegaMenu.js.map +1 -1
  504. package/dist/modules/seo/Meta.d.ts +40 -2
  505. package/dist/modules/seo/Meta.d.ts.map +1 -1
  506. package/dist/modules/seo/Meta.js.map +1 -1
  507. package/dist/modules/seo/Schema.d.ts +2 -1
  508. package/dist/modules/seo/Schema.d.ts.map +1 -1
  509. package/dist/modules/seo/Schema.js +1 -2
  510. package/dist/modules/seo/Schema.js.map +1 -1
  511. package/dist/next/index.d.ts +35 -0
  512. package/dist/next/index.d.ts.map +1 -0
  513. package/dist/next/index.js +56 -0
  514. package/dist/next/index.js.map +1 -0
  515. package/dist/package.json +52 -7
  516. package/dist/scripts/init-agent.js +156 -0
  517. package/dist/scripts/validate-ai-code.js +213 -0
  518. package/dist/server/og-utils.d.ts +9 -3
  519. package/dist/server/og-utils.d.ts.map +1 -1
  520. package/dist/server/og-utils.js +15 -9
  521. package/dist/server/og-utils.js.map +1 -1
  522. package/dist/styles/breakpoints.scss +16 -5
  523. package/dist/test/setup.js +21 -0
  524. package/dist/test/setup.js.map +1 -1
  525. package/dist/types.d.ts +13 -1
  526. package/dist/types.d.ts.map +1 -1
  527. package/dist/types.js.map +1 -1
  528. package/dist/utils/colorScheme.d.ts +35 -0
  529. package/dist/utils/colorScheme.d.ts.map +1 -0
  530. package/dist/utils/colorScheme.js +140 -0
  531. package/dist/utils/colorScheme.js.map +1 -0
  532. package/dist/utils/index.d.ts +2 -0
  533. package/dist/utils/index.d.ts.map +1 -1
  534. package/dist/utils/index.js +2 -0
  535. package/dist/utils/index.js.map +1 -1
  536. package/dist/utils/navMatch.d.ts +21 -0
  537. package/dist/utils/navMatch.d.ts.map +1 -0
  538. package/dist/utils/navMatch.js +26 -0
  539. package/dist/utils/navMatch.js.map +1 -0
  540. package/package.json +66 -11
  541. package/scripts/validate-ai-code.js +74 -10
  542. package/dist/css/styles.css.map +0 -1
  543. package/dist/css/tokens.css.map +0 -1
  544. package/dist/hooks/useResponsiveClasses.d.ts +0 -9
  545. package/dist/hooks/useResponsiveClasses.d.ts.map +0 -1
  546. package/dist/hooks/useResponsiveClasses.js +0 -293
  547. package/dist/hooks/useResponsiveClasses.js.map +0 -1
  548. package/dist/styles/background.scss +0 -423
  549. package/dist/styles/border.scss +0 -546
  550. package/dist/styles/color.scss +0 -183
  551. package/dist/styles/display.scss +0 -391
  552. package/dist/styles/flex.scss +0 -518
  553. package/dist/styles/global.scss +0 -36
  554. package/dist/styles/grid.scss +0 -293
  555. package/dist/styles/index.scss +0 -14
  556. package/dist/styles/position.scss +0 -1549
  557. package/dist/styles/shadow.scss +0 -19
  558. package/dist/styles/size.scss +0 -53
  559. package/dist/styles/spacing.scss +0 -1505
  560. package/dist/styles/typography.scss +0 -223
  561. package/dist/styles/utilities.scss +0 -23
  562. package/dist/tokens/border.scss +0 -95
  563. package/dist/tokens/data.scss +0 -107
  564. package/dist/tokens/function.scss +0 -742
  565. package/dist/tokens/index.scss +0 -8
  566. package/dist/tokens/layout.scss +0 -275
  567. package/dist/tokens/scheme.scss +0 -352
  568. package/dist/tokens/shadow.scss +0 -7
  569. package/dist/tokens/theme.scss +0 -657
  570. package/dist/tokens/typography.scss +0 -118
  571. package/next-env.d.ts +0 -5
  572. package/scripts/copy-files.js +0 -103
  573. package/scripts/generate-ai-spec.js +0 -464
  574. package/scripts/generate-emoji-data.js +0 -128
  575. package/scss.d.ts +0 -4
  576. package/tsconfig.vitest.json +0 -20
  577. package/vitest.config.ts +0 -19
package/ai/gotchas.json CHANGED
@@ -1,86 +1,143 @@
1
1
  {
2
2
  "Background.gradient.width": {
3
3
  "rule": "Quarter-percent units: 400 = 100% of container. Soft glows use width 100–200, not 500.",
4
- "components": ["Background"]
4
+ "components": [
5
+ "Background"
6
+ ]
5
7
  },
6
8
  "Background.gradient.x": {
7
9
  "rule": "x/y are percent positions of the container (50/50 = center).",
8
- "components": ["Background"]
10
+ "components": [
11
+ "Background"
12
+ ]
9
13
  },
10
14
  "Background.absolute": {
11
15
  "rule": "Every absolute decorative layer needs top=\"0\" left=\"0\" or it offsets by parent padding.",
12
- "components": ["Background", "MatrixFx", "BlobFx"]
16
+ "components": [
17
+ "Background",
18
+ "MatrixFx",
19
+ "BlobFx"
20
+ ]
13
21
  },
14
22
  "Card.interactive": {
15
23
  "rule": "Card is for interactive surfaces only (href or onClick). Static panels use Column + background=\"surface\" border=\"neutral-alpha-weak\" radius=\"l\".",
16
- "components": ["Card"]
24
+ "components": [
25
+ "Card"
26
+ ]
17
27
  },
18
28
  "Fade.edge": {
19
29
  "rule": "Fade is an edge overlay strip on scroll containers, not a content wrapper.",
20
- "components": ["Fade"]
30
+ "components": [
31
+ "Fade"
32
+ ]
21
33
  },
22
34
  "RevealFx.delay": {
23
- "rule": "delay is in seconds — stagger with delay={index * 0.1}, never index * 80.",
24
- "components": ["RevealFx"]
35
+ "rule": "delay is in milliseconds — stagger with delay={index * 100}, never index * 0.1 (that was 1.8.x; 2.0 reads 0.1 as a tenth of a millisecond, i.e. no stagger).",
36
+ "components": [
37
+ "RevealFx",
38
+ "ShineFx"
39
+ ]
25
40
  },
26
41
  "RevealFx.translateY": {
27
42
  "rule": "translateY as a number is in rem. Use translateY={1} or token \"16\" (1rem); 16 means 16rem.",
28
- "components": ["RevealFx"]
43
+ "components": [
44
+ "RevealFx"
45
+ ]
29
46
  },
30
47
  "LogoCloud.columns": {
31
48
  "rule": "LogoCloud extends Grid — always set columns and responsive overrides or logos stack in one column.",
32
- "components": ["LogoCloud"]
49
+ "components": [
50
+ "LogoCloud"
51
+ ]
33
52
  },
34
53
  "StatusIndicator.color": {
35
54
  "rule": "StatusIndicator uses color=\"green\" | \"red\" | \"orange\" | \"gray\" etc. — not variant or semantic scheme names.",
36
- "components": ["StatusIndicator"]
55
+ "components": [
56
+ "StatusIndicator"
57
+ ]
37
58
  },
38
59
  "Icon.names": {
39
- "rule": "Icon names must come from IconName in spec.json — never invent names like more, bell, arrowRight.",
40
- "components": ["Icon", "Button", "IconButton"]
60
+ "rule": "Icon names must come from iconNames in spec.json, which is a real union in 2.0 (an unregistered name is a type error, not a blank space). Do not guess a plausible name, and do not cast one with `as IconName` to silence the check. Brand marks are not in the set — an app registers those itself by augmenting IconLibraryOverrides.",
61
+ "components": [
62
+ "Icon",
63
+ "Button",
64
+ "IconButton"
65
+ ]
41
66
  },
42
67
  "Badge.duplicate": {
43
68
  "rule": "Do not pass the same text as both title prop and children — it renders twice.",
44
- "components": ["Badge"]
69
+ "components": [
70
+ "Badge"
71
+ ]
45
72
  },
46
73
  "Tag.duplicate": {
47
74
  "rule": "Do not pass the same text as both label prop and children — it renders twice.",
48
- "components": ["Tag"]
75
+ "components": [
76
+ "Tag"
77
+ ]
49
78
  },
50
79
  "color.tokens": {
51
80
  "rule": "Colors are semantic tokens ({scheme}-{weight}), never hex/rgb. background also accepts surface | overlay | page | transparent.",
52
- "components": ["Column", "Row", "Text", "Button"]
81
+ "components": [
82
+ "Column",
83
+ "Row",
84
+ "Text",
85
+ "Button"
86
+ ]
53
87
  },
54
88
  "color.background-weak": {
55
89
  "rule": "*-background-weak is nearly the page color — invisible as accent. Use alpha tokens (brand-alpha-medium) for glows.",
56
- "components": ["Background"]
90
+ "components": [
91
+ "Background"
92
+ ]
57
93
  },
58
94
  "layout.shorthands": {
59
95
  "rule": "Use fill not fillWidth fillHeight; center not horizontal=\"center\" vertical=\"center\"; Row/Column not Flex direction=.",
60
- "components": ["Row", "Column", "Flex", "Grid"]
96
+ "components": [
97
+ "Row",
98
+ "Column",
99
+ "Flex",
100
+ "Grid"
101
+ ]
61
102
  },
62
103
  "layout.defaults": {
63
104
  "rule": "Never write props equal to defaults: position=\"relative\", direction on Row/Column, variant=\"primary\" on Button.",
64
- "components": ["Row", "Column", "Button"]
105
+ "components": [
106
+ "Row",
107
+ "Column",
108
+ "Button"
109
+ ]
65
110
  },
66
111
  "section.gaps": {
67
112
  "rule": "Gap between page sections: 80–160 (typical 104). Inside sections: 24–40.",
68
- "components": ["Column"]
113
+ "components": [
114
+ "Column"
115
+ ]
69
116
  },
70
117
  "heading.scale": {
71
118
  "rule": "Hero = display-strong-l/xl; section titles = display-strong-xs/s — never heading-* for section titles.",
72
- "components": ["Heading"]
119
+ "components": [
120
+ "Heading"
121
+ ]
73
122
  },
74
123
  "animation.budget": {
75
124
  "rule": "Entry animation budget: hero + at most 1–2 key moments. Animate coherent blocks all-or-none within a sibling set.",
76
- "components": ["RevealFx", "CountFx"]
125
+ "components": [
126
+ "RevealFx",
127
+ "CountFx"
128
+ ]
77
129
  },
78
130
  "CountFx.trigger": {
79
131
  "rule": "CountFx has no trigger prop — drive value from useInViewport latch instead.",
80
- "components": ["CountFx"]
132
+ "components": [
133
+ "CountFx"
134
+ ]
81
135
  },
82
136
  "overflow.hero": {
83
137
  "rule": "overflow=\"hidden\" on full-bleed sections clips glows into hard bands — only use when parent has radius.",
84
- "components": ["Column", "Background"]
138
+ "components": [
139
+ "Column",
140
+ "Background"
141
+ ]
85
142
  }
86
143
  }
package/ai/layouts.md ADDED
@@ -0,0 +1,154 @@
1
+ # Once UI — application layouts
2
+
3
+ Recipes for the shells a product sits inside, as opposed to the decoration in
4
+ `recipes.md`. Each is the shape a working product converged on, not a sketch.
5
+
6
+ Use them verbatim, then adjust. The values that look arbitrary usually are not —
7
+ the notes say which ones matter and why.
8
+
9
+ All three compile: they are also `ai/examples/app-shell.tsx`, which `pnpm
10
+ typecheck` covers, so a renamed prop breaks the recipe rather than leaving it
11
+ quietly wrong.
12
+
13
+ ## 1. App shell with a sidebar
14
+
15
+ The one agents get wrong most often. A dashboard built without this scrolls the
16
+ whole document, so the header and sidebar slide away and the nav has to be
17
+ scrolled back to.
18
+
19
+ ```tsx
20
+ <Column fill horizontal="center" flex={1}>
21
+ <Header /> {/* 56px tall */}
22
+ <Row fill paddingX="8">
23
+ <Sidebar s={{ hide: true }} maxWidth={18} fitHeight position="sticky" top="56" />
24
+ <Row fill horizontal="center" topRadius="l" overflow="hidden">
25
+ <Row
26
+ height="calc(100dvh - var(--static-space-56))"
27
+ overflowY="auto"
28
+ topRadius="l"
29
+ horizontal="center"
30
+ fillWidth
31
+ background="surface">
32
+ <Column maxWidth="xl" gap="m" paddingY="32" fitHeight>
33
+ {children}
34
+ </Column>
35
+ </Row>
36
+ </Row>
37
+ </Row>
38
+ </Column>
39
+ ```
40
+
41
+ What each part is doing:
42
+
43
+ - **The pane scrolls, not the page.** `height: calc(100dvh - <header>)` plus
44
+ `overflowY="auto"` is what keeps the header and sidebar in place. `dvh`, not
45
+ `vh` — on mobile `vh` ignores the browser chrome and the pane runs off-screen.
46
+ - **`position="sticky" top="56"`** on the sidebar, matching the header height.
47
+ `fitHeight` so it does not stretch and fight the sticky.
48
+ - **`topRadius="l"` + `background="surface"`** is what makes the content read as
49
+ a panel sitting on the page rather than the page itself. The radius is on the
50
+ top only, since the bottom is off-screen.
51
+ - **`s={{ hide: true }}`** rather than a media query. The mobile nav is a
52
+ separate surface, not this one reflowed.
53
+ - **`maxWidth="xl"`** inside the pane. A dashboard is wider than a document;
54
+ `"m"` is for reading.
55
+
56
+ ## 2. Data-driven navigation
57
+
58
+ ```tsx
59
+ import { NavGroup, NavItem, selectNavHref } from "@once-ui-system/core";
60
+
61
+ const current = selectNavHref(pathname, nav.flatMap((i) =>
62
+ i.items ? i.items.map((s) => s.href) : [i.href],
63
+ ));
64
+
65
+ <Column fill gap="4" paddingX="8">
66
+ {nav.map((item) =>
67
+ item.items ? (
68
+ <NavGroup
69
+ key={item.key}
70
+ label={item.label}
71
+ icon={item.icon}
72
+ defaultOpen={item.items.some((s) => s.href === current)}>
73
+ {item.items.map((sub) => (
74
+ <NavItem
75
+ key={sub.href}
76
+ href={sub.href}
77
+ label={sub.label}
78
+ badge={sub.badge}
79
+ selected={sub.href === current}
80
+ />
81
+ ))}
82
+ </NavGroup>
83
+ ) : (
84
+ <NavItem
85
+ key={item.href}
86
+ href={item.href}
87
+ icon={item.icon}
88
+ label={item.label}
89
+ selected={item.href === current}
90
+ />
91
+ ),
92
+ )}
93
+ </Column>
94
+ ```
95
+
96
+ - **`selectNavHref` over `===` or `startsWith`.** An equality check leaves a
97
+ nested route (`/settings/billing/invoices/42`) with nothing highlighted; a
98
+ prefix check lights the parent up alongside its child. It returns the longest
99
+ href that matches, which is the right one.
100
+ - **Compute `current` once** for the whole tree, not per item — a child needs to
101
+ know about its siblings to know it is the deepest match.
102
+ - **`defaultOpen` from the match**, so the group holding the current page is open
103
+ on arrival.
104
+ - Child items take **no icon**. The rail inside `NavGroup` carries the hierarchy;
105
+ a second column of icons competes with it.
106
+
107
+ ## 3. Editor shell
108
+
109
+ Two panes and a timeline — the shape of a video editor, a page builder, a
110
+ diff view.
111
+
112
+ ```tsx
113
+ <Column fill>
114
+ <SplitView
115
+ fill
116
+ leftPanel={<Column fill overflowY="auto">{/* layers, blocks, files */}</Column>}
117
+ rightPanel={<Column fill overflowY="auto">{/* canvas, preview */}</Column>}
118
+ defaultSplit={0.28}
119
+ minSplit={0.2}
120
+ maxSplit={0.6}
121
+ collapseBelow="s"
122
+ labels={{ left: "Layers", right: "Canvas" }}
123
+ />
124
+ <Scrubber
125
+ duration={duration}
126
+ value={time}
127
+ onChange={setTime}
128
+ tracks={tracks}
129
+ onGestureStart={pause}
130
+ />
131
+ </Column>
132
+ ```
133
+
134
+ - **`overflowY="auto"` on each panel, not on the SplitView.** The divider needs
135
+ the container to stay put while the panes scroll independently.
136
+ - **`collapseBelow` + `labels`.** Below the breakpoint the split becomes tabs, and
137
+ `labels` is what they say. Without it the tabs are unlabelled.
138
+ - **`onGestureStart` pauses playback.** Scrubbing while playing fights the
139
+ playhead — the drag sets a time, playback immediately moves it.
140
+ - **The timeline is a sibling of the split, not inside it.** It spans both panes,
141
+ and putting it in one makes the divider drag it.
142
+
143
+ ## Anti-patterns
144
+
145
+ - A dashboard with no scrolling pane — the whole document scrolls and the nav
146
+ leaves with it.
147
+ - `100vh` in an app shell. Use `100dvh`; `vh` is wrong on mobile the moment the
148
+ browser chrome shows or hides.
149
+ - A sticky sidebar without `fitHeight` — it stretches to the row and the sticky
150
+ never engages.
151
+ - `pathname === href` or `startsWith` for nav selection. Use `selectNavHref`.
152
+ - Icons on both a NavGroup and its children — two columns of icons, no hierarchy.
153
+ - `overflow` on the SplitView instead of on its panels — the divider stops
154
+ tracking the pointer.
package/ai/manifest.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
- "version": "1.8.3",
3
- "generated": "2026-08-27",
2
+ "version": "2.0.0-alpha.0",
3
+ "generated": "2026-09-16",
4
4
  "files": {
5
5
  "spec": "spec.json",
6
6
  "catalog": "catalog.json",
7
7
  "rules": "rules.compact.md",
8
8
  "rulesFull": "rules.md",
9
9
  "recipes": "recipes.md",
10
+ "layouts": "layouts.md",
10
11
  "gotchas": "gotchas.json",
11
12
  "tasks": "tasks/index.json",
12
13
  "examples": "examples/",
package/ai/recipes.md CHANGED
@@ -1,7 +1,8 @@
1
- # Once UI — decoration recipes
1
+ # Once UI — decoration and restraint recipes
2
2
 
3
- Curated decorative patterns that keep pages premium without going over the top.
4
- Use them verbatim, then adjust values. All units follow rules.md #21–24.
3
+ Curated patterns that keep pages premium without going over the top: decorative
4
+ layers that carry a section, and controls that earn their room back. Use them
5
+ verbatim, then adjust values. All units follow rules.md #21–24.
5
6
 
6
7
  ## Budget (hard limits)
7
8
 
@@ -129,7 +130,7 @@ useEffect(() => {
129
130
 
130
131
  <Grid ref={ref} columns="3" gap="16" s={{ columns: 1 }}>
131
132
  {items.map((item, index) => (
132
- <RevealFx key={item.id} trigger={seen} translateY="8" delay={index * 0.1}>
133
+ <RevealFx key={item.id} revealed={seen} translateY="8" delay={index * 100}>
133
134
  <Card ... />
134
135
  </RevealFx>
135
136
  ))}
@@ -138,8 +139,52 @@ useEffect(() => {
138
139
 
139
140
  For stats, drive `CountFx` value from the same latch: `<CountFx value={seen ? 2400 : 0} separator="," />`.
140
141
 
142
+ ## 8. Reveal on hover (controls that earn their room back)
143
+
144
+ A control that must be reachable from every page but is used once a session does
145
+ not need permanent width. Show its current state; reveal the options on hover or
146
+ focus.
147
+
148
+ `ThemeSwitcher` ships this as a prop:
149
+
150
+ ```tsx
151
+ <ThemeSwitcher collapsed />
152
+ ```
153
+
154
+ For any other toggle group, the pattern is the same three rules — and all three
155
+ are load-bearing, because hover-to-reveal is one of the easiest ways to ship an
156
+ inaccessible control:
157
+
158
+ - **Open on `:focus-within` as well as `:hover`,** and keep the hidden options
159
+ focusable. Collapse them with `max-width: 0` and `overflow: hidden`, never
160
+ `display: none` or `visibility: hidden` — those remove the tab stops, and then
161
+ the only way to reach the options is with a mouse.
162
+ - **Stay open under `@media (hover: none)`.** On a touch device the first tap
163
+ lands on the visible control, which means the tap that was meant to open the
164
+ group has already committed to an option.
165
+ - **Animate width only, and drop it under `prefers-reduced-motion`.** The
166
+ control must do exactly the same thing with the transition off.
167
+
168
+ ```scss
169
+ .group { overflow: hidden; }
170
+ .group .option { overflow: hidden; max-width: var(--static-space-40); transition: max-width var(--transition-duration-micro-medium) ease; }
171
+ .group .option.inactive { max-width: 0; opacity: 0; }
172
+ .group:hover .option.inactive,
173
+ .group:focus-within .option.inactive { max-width: var(--static-space-40); opacity: 1; }
174
+
175
+ @media (hover: none) { .group .option.inactive { max-width: var(--static-space-40); opacity: 1; } }
176
+ @media (prefers-reduced-motion: reduce) { .group .option { transition: none; } }
177
+ ```
178
+
179
+ Use it for theme, density, or view-mode switchers in a header or a footer. Do
180
+ not use it for anything a visitor needs to *see* the state of at a glance across
181
+ options, for primary navigation, or for a destructive action — a control that
182
+ hides until pointed at is a control nobody finds.
183
+
141
184
  ## Anti-patterns
142
185
 
186
+ - **Hover-only reveals.** A group that opens on `:hover` but not `:focus-within`, or that collapses with `display: none`, is unreachable by keyboard and unusable by touch. See #8.
187
+
143
188
  - Glow with `colorStart: "brand-background-weak"` — invisible against the page; use alpha tokens.
144
189
  - `width: 500` gradients — that's 125% of the container blown past its edges; stay ≤ 200 for glows.
145
190
  - Background layers without `top="0" left="0"` inside padded parents — misaligned.
@@ -1,6 +1,6 @@
1
1
  # Once UI — compact codegen rules
2
2
 
3
- Load with task bundle from `@once-ui-system/core/ai/tasks/{intent}.json`. For production-quality composition, read matching Pro blocks from `examples/blocks/manifest.json`. Fetch component slices on demand.
3
+ Load with task bundle from `@once-ui-system/core/ai/tasks/{intent}.json`. For an app shell, a sidebar nav or an editor, read `ai/layouts.md` first — those are the shapes that are hard to get right from props alone. For production-quality composition, read matching Pro blocks from `examples/blocks/manifest.json`. Fetch component slices on demand.
4
4
 
5
5
  ## Layout
6
6
 
@@ -47,9 +47,9 @@ Absolute layers always: `position="absolute" top="0" left="0" fill pointerEvents
47
47
 
48
48
  ## Motion
49
49
 
50
- - `RevealFx delay` in **seconds**: `delay={index * 0.1}`
50
+ - `RevealFx delay` (and `ShineFx speed`) in **milliseconds**: `delay={index * 100}` — `* 0.1` was 1.8.x
51
51
  - `RevealFx translateY`: number = rem; prefer `"8"`–`"16"` tokens
52
- - Viewport-trigger with `useInViewport` + latch; `CountFx` driven by `value`, no trigger prop
52
+ - Viewport-reveal with `useInViewport` + latch into `RevealFx revealed`; `CountFx` driven by `value`, no trigger prop
53
53
  - Animate all siblings in a set or none — never one lone animated card
54
54
 
55
55
  ## Components
@@ -64,6 +64,21 @@ Absolute layers always: `position="absolute" top="0" left="0" fill pointerEvents
64
64
  | Icons | `IconName` from spec only |
65
65
  | Logos grid | `LogoCloud` with `columns` set |
66
66
 
67
+ ## Imports
68
+
69
+ Most things come from the package root. Three modules do not, because their
70
+ dependencies are optional peers:
71
+
72
+ | Import | From |
73
+ |--------|------|
74
+ | charts, gauges, chart chrome | `@once-ui-system/core/data` (needs `recharts`) |
75
+ | `CodeBlock` | `@once-ui-system/core/code` (needs `prismjs`) |
76
+ | `MediaUpload` | `@once-ui-system/core/media` (needs `compressorjs`) |
77
+
78
+ Naming one of these from the root does not resolve. `IconName` is a real union,
79
+ so an unregistered icon name is a type error, not a blank space — take names
80
+ from `spec.json`.
81
+
67
82
  ## Defaults — omit these
68
83
 
69
84
  `position="relative"`, `direction` on Row/Column, `variant="primary"` on Button, `size="m"` when default.
package/ai/rules.md CHANGED
@@ -47,7 +47,7 @@ If you can't ask (or the user says "you decide"), default to: restrained, center
47
47
 
48
48
  ## Spacing and sizing
49
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"`).
50
+ 4. Use spacing tokens, never raw CSS: `gap`, `padding`, `margin`, `paddingX/Y`, `marginX/Y` accept the full `SpacingToken` scale (`"0" "1" "2" "4" "8" "12" "16" "20" "24" "32" "40" "48" "56" "64" "80" "104" "128" "160"`, or `"xs" "s" "m" "l" "xl"`). The top of the scale is what rule 17 calls for between sections — it is not an extension, it is part of the same list.
51
51
 
52
52
  ```tsx
53
53
  // Good
@@ -109,9 +109,9 @@ If you can't ask (or the user says "you decide"), default to: restrained, center
109
109
  - `CursorCard`, `HoverCard`, `ContextMenu`, `EmojiPicker`, `CompareImage`, `OgCard`, `Timeline`, `MasonryGrid`, `InfiniteScroll`, `SegmentedControl`, `Kbar` (command palette)
110
110
  - Forms: `Input`, `PasswordInput`, `OTPInput`, `NumberInput`, `TagInput`, `Select`, `DatePicker`, `DateRangePicker`, `ColorInput`, `Slider`, `Switch`, `Checkbox`, `Chip`
111
111
 
112
- 14. Buttons: `variant` = `primary | secondary | tertiary | danger`; pair with `prefixIcon`/`suffixIcon` (icon names, not elements). `IconButton` for icon-only actions with `tooltip`.
112
+ 14. Buttons: `variant` = `primary | secondary | tertiary | quaternary | subtle | danger | success | warning | ghost | link` (the slice is authoritative; `primary` is the default); pair with `prefixIcon`/`suffixIcon` (icon names, not elements). `IconButton` for icon-only actions with `tooltip`.
113
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.
114
+ 14b. Icon names must come from `iconNames` in spec.json. In 2.0 `IconName` is a real union, so an unregistered name is a type error rather than a blank space — do not guess a plausible one, and never reach for `as IconName` to silence the check. If no registered icon fits, omit the icon. The registry is 99 icons; brand marks (github, discord, google) are deliberately not among them, so an app registers its own.
115
115
 
116
116
  14c. Components with a text prop render it — never pass the same text as both prop and children, it renders twice:
117
117
 
@@ -155,9 +155,47 @@ If you can't ask (or the user says "you decide"), default to: restrained, center
155
155
  // Good eyebrow
156
156
  <Text variant="label-default-s" onBackground="brand-medium">Pricing</Text>
157
157
  // Bad eyebrow
158
- <Tag variant="neutral" prefixIcon="sparkle">Pricing</Tag>
158
+ <Tag scheme="neutral" prefixIcon="sparkle">Pricing</Tag>
159
159
  ```
160
160
 
161
+ 20b. **Proportion is a decision, not a leftover.** Two columns in a row finish at
162
+ roughly the same place, or one of them is wrong. A tall card beside a strip of
163
+ small controls leaves a column of dead space that reads as an unfinished page —
164
+ and the fix is almost never more whitespace tokens.
165
+
166
+ Give the thin side real content instead. Tiles grow to carry their own height,
167
+ with a placeholder, a preview, a swatch, a count — something true about the
168
+ thing they stand for. Then keep them quiet: low-contrast surfaces, small labels,
169
+ no competing headline. A grid of twenty loud tiles takes the section away from
170
+ the card it was meant to support.
171
+
172
+ ```tsx
173
+ // Bad: a tall card and 20 chips, most of the row empty
174
+ <Row fillWidth gap="32">
175
+ <Column flex={1} maxWidth={26}><FeatureCard /></Column>
176
+ <Column flex={1}><Row wrap gap="4">{items.map(i => <Button key={i} size="s">{i}</Button>)}</Row></Column>
177
+ </Row>
178
+
179
+ // Good: both sides carry weight, the card still leads
180
+ <Row fillWidth gap="32">
181
+ <Column flex={2}><FeatureCard /></Column>
182
+ <Column flex={3}>
183
+ <Grid columns={5} s={{ columns: 3 }} gap="8" fillWidth>
184
+ {items.map(i => (
185
+ <Column key={i} aspectRatio="1 / 1" padding="12" radius="l"
186
+ background="page" border="neutral-alpha-weak" vertical="between">
187
+ {/* a preview of the thing, not just its name */}
188
+ </Column>
189
+ ))}
190
+ </Grid>
191
+ </Column>
192
+ </Row>
193
+ ```
194
+
195
+ Check it by squinting at the two columns' bottom edges. If one ends halfway up
196
+ the other, change the flex ratio, the tile size, or what the tiles contain —
197
+ in that order.
198
+
161
199
  ## Decorative layers
162
200
 
163
201
  21. Every absolute decorative layer uses the full recipe — `top="0" left="0"` are required or the layer gets offset by parent padding:
@@ -184,21 +222,21 @@ Siblings holding content get `zIndex={1}`. `overflow="hidden"` goes on the paren
184
222
 
185
223
  ## Effect units
186
224
 
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.
225
+ 24. `RevealFx`: `delay` is in **milliseconds** — stagger with `delay={index * 100}`, never `index * 0.1` (that was 1.8.x, and 2.0 reads it as a tenth of a millisecond, i.e. no stagger at all). `ShineFx.speed` is milliseconds for the same reason. `translateY` as a number is in **rem** — use `translateY={1}` or a token like `"16"` (1rem); `16` means 16rem.
188
226
 
189
227
  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
228
 
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.
229
+ 26. Use decoration recipes from `recipes.md` verbatim, then adjust. Application shells — a dashboard with a sidebar, a data-driven nav, a two-pane editor — come from `layouts.md` the same way. 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
230
 
193
231
  ## Motion
194
232
 
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.
233
+ 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 * 100}` max), and only on elements worth leading the eye to — the hero heading, stat numbers, the highlighted card in a set.
196
234
 
197
235
  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
236
 
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.
237
+ 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 / 100 / 200`), not individual text fragments. One entrance moment per viewport: if the hero animates, the cards below it don't.
200
238
 
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:
239
+ 29. Trigger below-the-fold animations with `useInViewport`, latched so they play once. `RevealFx` takes `revealed`; `CountFx` has no trigger prop — drive its `value` instead:
202
240
 
203
241
  ```tsx
204
242
  const ref = useRef<HTMLDivElement>(null);
@@ -209,9 +247,29 @@ useEffect(() => {
209
247
  }, [inViewport]);
210
248
 
211
249
  <Column ref={ref} gap="16">
212
- <RevealFx trigger={seen} translateY="8">...</RevealFx>
250
+ <RevealFx revealed={seen} translateY="8">...</RevealFx>
213
251
  <CountFx value={seen ? 2400 : 0} speed={1500} separator="," variant="display-strong-m" />
214
252
  </Column>
215
253
  ```
216
254
 
217
255
  Without this, mount-timed animations play while still off-screen and the user scrolls into an already-finished state.
256
+
257
+ ## Imports
258
+
259
+ 30. Most things come from the package root, but three modules do not, because
260
+ their dependencies are optional peers and a root re-export would drag the
261
+ specifier into every consumer's module graph:
262
+
263
+ | Import | From | Peer the app installs |
264
+ |--------|------|-----------------------|
265
+ | charts, gauges, chart chrome | `@once-ui-system/core/data` | `recharts` |
266
+ | `CodeBlock` | `@once-ui-system/core/code` | `prismjs` |
267
+ | `MediaUpload` | `@once-ui-system/core/media` | `compressorjs` |
268
+
269
+ Naming one of these from the root does not resolve. Each component slice in
270
+ `ai/components/` carries the specifier to import it from.
271
+
272
+ 31. `IconName` is a real union, not `string`. An unregistered name is a type
273
+ error now, where it used to render a blank space with a console warning — so
274
+ take icon names from `spec.json`'s `iconNames` rather than guessing a plausible
275
+ one. An app registers its own by augmenting `IconLibraryOverrides`.