decantr 0.9.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 (382) hide show
  1. package/AGENTS.md +868 -0
  2. package/CHANGELOG.md +255 -0
  3. package/CLAUDE.md +178 -0
  4. package/LICENSE +21 -0
  5. package/README.md +229 -0
  6. package/cli/art.js +127 -0
  7. package/cli/commands/a11y.js +61 -0
  8. package/cli/commands/audit.js +225 -0
  9. package/cli/commands/build.js +38 -0
  10. package/cli/commands/dev.js +18 -0
  11. package/cli/commands/doctor.js +197 -0
  12. package/cli/commands/figma-sync.js +48 -0
  13. package/cli/commands/figma-tokens.js +55 -0
  14. package/cli/commands/generate.js +26 -0
  15. package/cli/commands/init.js +116 -0
  16. package/cli/commands/lint.js +209 -0
  17. package/cli/commands/mcp.js +530 -0
  18. package/cli/commands/migrate.js +175 -0
  19. package/cli/commands/test.js +38 -0
  20. package/cli/commands/validate.js +354 -0
  21. package/cli/index.js +113 -0
  22. package/package.json +95 -0
  23. package/reference/atoms.md +517 -0
  24. package/reference/behaviors.md +384 -0
  25. package/reference/build-tooling.md +275 -0
  26. package/reference/color-guidelines.md +965 -0
  27. package/reference/component-lifecycle.md +137 -0
  28. package/reference/compound-spacing.md +95 -0
  29. package/reference/decantation-process.md +499 -0
  30. package/reference/dev-server-routes.md +93 -0
  31. package/reference/form-system.md +253 -0
  32. package/reference/i18n.md +336 -0
  33. package/reference/icons.md +576 -0
  34. package/reference/llm-primer.md +953 -0
  35. package/reference/plugins.md +252 -0
  36. package/reference/registry-consumption.md +76 -0
  37. package/reference/router.md +217 -0
  38. package/reference/shells.md +116 -0
  39. package/reference/spatial-guidelines.md +541 -0
  40. package/reference/ssr.md +234 -0
  41. package/reference/state-data.md +215 -0
  42. package/reference/state-patterns.md +166 -0
  43. package/reference/state.md +194 -0
  44. package/reference/style-system.md +110 -0
  45. package/reference/tokens.md +460 -0
  46. package/src/app.js +19 -0
  47. package/src/chart/_animate.js +266 -0
  48. package/src/chart/_base.js +109 -0
  49. package/src/chart/_data.js +209 -0
  50. package/src/chart/_format.js +106 -0
  51. package/src/chart/_interact.js +364 -0
  52. package/src/chart/_palette.js +105 -0
  53. package/src/chart/_renderer.js +52 -0
  54. package/src/chart/_scene.js +262 -0
  55. package/src/chart/_shared.js +371 -0
  56. package/src/chart/index.js +637 -0
  57. package/src/chart/layouts/_layout-base.js +328 -0
  58. package/src/chart/layouts/cartesian.js +148 -0
  59. package/src/chart/layouts/hierarchy.js +562 -0
  60. package/src/chart/layouts/polar.js +101 -0
  61. package/src/chart/renderers/canvas.js +179 -0
  62. package/src/chart/renderers/svg.js +256 -0
  63. package/src/chart/renderers/webgpu.js +715 -0
  64. package/src/chart/types/_type-base.js +26 -0
  65. package/src/chart/types/area.js +134 -0
  66. package/src/chart/types/bar.js +173 -0
  67. package/src/chart/types/box-plot.js +125 -0
  68. package/src/chart/types/bubble.js +63 -0
  69. package/src/chart/types/candlestick.js +115 -0
  70. package/src/chart/types/chord.js +85 -0
  71. package/src/chart/types/combination.js +108 -0
  72. package/src/chart/types/funnel.js +68 -0
  73. package/src/chart/types/gauge.js +163 -0
  74. package/src/chart/types/heatmap.js +98 -0
  75. package/src/chart/types/histogram.js +71 -0
  76. package/src/chart/types/line.js +111 -0
  77. package/src/chart/types/org-chart.js +93 -0
  78. package/src/chart/types/pie.js +81 -0
  79. package/src/chart/types/radar.js +96 -0
  80. package/src/chart/types/radial.js +68 -0
  81. package/src/chart/types/range-area.js +55 -0
  82. package/src/chart/types/range-bar.js +61 -0
  83. package/src/chart/types/sankey.js +73 -0
  84. package/src/chart/types/scatter.js +66 -0
  85. package/src/chart/types/sparkline.js +81 -0
  86. package/src/chart/types/sunburst.js +69 -0
  87. package/src/chart/types/swimlane.js +88 -0
  88. package/src/chart/types/treemap.js +62 -0
  89. package/src/chart/types/waterfall.js +100 -0
  90. package/src/components/_base.js +1658 -0
  91. package/src/components/_behaviors.js +1140 -0
  92. package/src/components/_primitives.js +534 -0
  93. package/src/components/_qr-encoder.js +539 -0
  94. package/src/components/accordion.js +207 -0
  95. package/src/components/affix.js +62 -0
  96. package/src/components/alert-dialog.js +75 -0
  97. package/src/components/alert.js +47 -0
  98. package/src/components/aspect-ratio.js +24 -0
  99. package/src/components/avatar-group.js +55 -0
  100. package/src/components/avatar.js +38 -0
  101. package/src/components/back-top.js +75 -0
  102. package/src/components/badge.js +74 -0
  103. package/src/components/banner.js +68 -0
  104. package/src/components/breadcrumb.js +162 -0
  105. package/src/components/button.js +115 -0
  106. package/src/components/calendar.js +131 -0
  107. package/src/components/card.js +192 -0
  108. package/src/components/carousel.js +98 -0
  109. package/src/components/cascader.js +261 -0
  110. package/src/components/checkbox.js +80 -0
  111. package/src/components/chip.js +81 -0
  112. package/src/components/code-block.js +82 -0
  113. package/src/components/collapsible.js +50 -0
  114. package/src/components/color-palette.js +438 -0
  115. package/src/components/color-picker.js +314 -0
  116. package/src/components/combobox.js +181 -0
  117. package/src/components/command.js +174 -0
  118. package/src/components/comment.js +206 -0
  119. package/src/components/context-menu.js +76 -0
  120. package/src/components/data-table.js +724 -0
  121. package/src/components/date-picker.js +217 -0
  122. package/src/components/date-range-picker.js +244 -0
  123. package/src/components/datetime-picker.js +271 -0
  124. package/src/components/descriptions.js +68 -0
  125. package/src/components/drawer.js +179 -0
  126. package/src/components/dropdown.js +88 -0
  127. package/src/components/empty.js +41 -0
  128. package/src/components/float-button.js +90 -0
  129. package/src/components/form.js +106 -0
  130. package/src/components/hover-card.js +49 -0
  131. package/src/components/icon.js +87 -0
  132. package/src/components/image.js +97 -0
  133. package/src/components/index.js +117 -0
  134. package/src/components/input-group.js +75 -0
  135. package/src/components/input-number.js +155 -0
  136. package/src/components/input-otp.js +178 -0
  137. package/src/components/input.js +91 -0
  138. package/src/components/kbd.js +36 -0
  139. package/src/components/label.js +25 -0
  140. package/src/components/list.js +118 -0
  141. package/src/components/masked-input.js +236 -0
  142. package/src/components/mentions.js +165 -0
  143. package/src/components/menu.js +259 -0
  144. package/src/components/message.js +80 -0
  145. package/src/components/modal.js +147 -0
  146. package/src/components/navigation-menu.js +166 -0
  147. package/src/components/notification.js +84 -0
  148. package/src/components/pagination.js +104 -0
  149. package/src/components/placeholder.js +132 -0
  150. package/src/components/popconfirm.js +70 -0
  151. package/src/components/popover.js +58 -0
  152. package/src/components/progress.js +61 -0
  153. package/src/components/qrcode.js +251 -0
  154. package/src/components/radiogroup.js +120 -0
  155. package/src/components/range-slider.js +176 -0
  156. package/src/components/rate.js +186 -0
  157. package/src/components/resizable.js +83 -0
  158. package/src/components/result.js +57 -0
  159. package/src/components/scroll-area.js +43 -0
  160. package/src/components/segmented.js +97 -0
  161. package/src/components/select.js +165 -0
  162. package/src/components/separator.js +31 -0
  163. package/src/components/shell.js +407 -0
  164. package/src/components/skeleton.js +39 -0
  165. package/src/components/slider.js +141 -0
  166. package/src/components/sortable-list.js +176 -0
  167. package/src/components/space.js +42 -0
  168. package/src/components/spinner.js +112 -0
  169. package/src/components/splitter.js +147 -0
  170. package/src/components/statistic.js +136 -0
  171. package/src/components/steps.js +99 -0
  172. package/src/components/switch.js +95 -0
  173. package/src/components/table.js +44 -0
  174. package/src/components/tabs.js +216 -0
  175. package/src/components/tag.js +115 -0
  176. package/src/components/textarea.js +82 -0
  177. package/src/components/time-picker.js +153 -0
  178. package/src/components/time-range-picker.js +170 -0
  179. package/src/components/timeline.js +226 -0
  180. package/src/components/toast.js +71 -0
  181. package/src/components/toggle.js +213 -0
  182. package/src/components/tooltip.js +57 -0
  183. package/src/components/tour.js +159 -0
  184. package/src/components/transfer.js +163 -0
  185. package/src/components/tree-select.js +274 -0
  186. package/src/components/tree.js +141 -0
  187. package/src/components/typography.js +136 -0
  188. package/src/components/upload.js +118 -0
  189. package/src/components/visually-hidden.js +20 -0
  190. package/src/components/watermark.js +124 -0
  191. package/src/core/index.js +539 -0
  192. package/src/core/lifecycle.js +69 -0
  193. package/src/css/atoms.js +651 -0
  194. package/src/css/components.js +940 -0
  195. package/src/css/derive.js +1296 -0
  196. package/src/css/index.js +265 -0
  197. package/src/css/runtime.js +268 -0
  198. package/src/css/styles/addons/bioluminescent.js +93 -0
  199. package/src/css/styles/addons/clay.js +70 -0
  200. package/src/css/styles/addons/clean.js +57 -0
  201. package/src/css/styles/addons/command-center.js +143 -0
  202. package/src/css/styles/addons/dopamine.js +83 -0
  203. package/src/css/styles/addons/editorial.js +80 -0
  204. package/src/css/styles/addons/glassmorphism.js +99 -0
  205. package/src/css/styles/addons/liquid-glass.js +105 -0
  206. package/src/css/styles/addons/prismatic.js +100 -0
  207. package/src/css/styles/addons/retro.js +63 -0
  208. package/src/css/styles/auradecantism.js +96 -0
  209. package/src/css/theme-registry.js +444 -0
  210. package/src/data/entity.js +281 -0
  211. package/src/data/index.js +13 -0
  212. package/src/data/persist.js +225 -0
  213. package/src/data/query.js +839 -0
  214. package/src/data/realtime.js +299 -0
  215. package/src/data/url.js +177 -0
  216. package/src/data/worker.js +134 -0
  217. package/src/explorer/archetypes.js +243 -0
  218. package/src/explorer/atoms.js +228 -0
  219. package/src/explorer/charts.js +497 -0
  220. package/src/explorer/components.js +129 -0
  221. package/src/explorer/foundations.js +949 -0
  222. package/src/explorer/icons.js +178 -0
  223. package/src/explorer/patterns.js +247 -0
  224. package/src/explorer/recipes.js +194 -0
  225. package/src/explorer/shared/pattern-examples.js +1337 -0
  226. package/src/explorer/shared/showcase-renderer.js +958 -0
  227. package/src/explorer/shared/spec-table.js +41 -0
  228. package/src/explorer/shared/usage-links.js +87 -0
  229. package/src/explorer/shell-config.js +10 -0
  230. package/src/explorer/shells.js +551 -0
  231. package/src/explorer/styles.js +161 -0
  232. package/src/explorer/tokens.js +262 -0
  233. package/src/explorer/tools.js +525 -0
  234. package/src/form/index.js +804 -0
  235. package/src/i18n/index.js +251 -0
  236. package/src/icons/essential.js +479 -0
  237. package/src/icons/index.js +53 -0
  238. package/src/plugins/index.js +282 -0
  239. package/src/registry/archetypes/content-site.json +71 -0
  240. package/src/registry/archetypes/docs-explorer.json +23 -0
  241. package/src/registry/archetypes/ecommerce.json +104 -0
  242. package/src/registry/archetypes/financial-dashboard.json +77 -0
  243. package/src/registry/archetypes/index.json +41 -0
  244. package/src/registry/archetypes/portfolio.json +82 -0
  245. package/src/registry/archetypes/recipe-community.json +159 -0
  246. package/src/registry/archetypes/saas-dashboard.json +86 -0
  247. package/src/registry/architect/cross-cutting.json +45 -0
  248. package/src/registry/architect/domains/ecommerce.json +294 -0
  249. package/src/registry/architect/domains/financial-services.json +302 -0
  250. package/src/registry/architect/index.json +26 -0
  251. package/src/registry/architect/traits.json +379 -0
  252. package/src/registry/atoms.json +16 -0
  253. package/src/registry/chart-showcase.json +160 -0
  254. package/src/registry/chart.json +136 -0
  255. package/src/registry/components.json +8616 -0
  256. package/src/registry/core.json +216 -0
  257. package/src/registry/css.json +319 -0
  258. package/src/registry/data.json +135 -0
  259. package/src/registry/foundations.json +11 -0
  260. package/src/registry/icons.json +463 -0
  261. package/src/registry/index.json +101 -0
  262. package/src/registry/patterns/activity-feed.json +37 -0
  263. package/src/registry/patterns/article-content.json +27 -0
  264. package/src/registry/patterns/auth-form.json +37 -0
  265. package/src/registry/patterns/author-card.json +20 -0
  266. package/src/registry/patterns/card-grid.json +127 -0
  267. package/src/registry/patterns/category-nav.json +26 -0
  268. package/src/registry/patterns/chart-grid.json +36 -0
  269. package/src/registry/patterns/chat-interface.json +37 -0
  270. package/src/registry/patterns/checklist-card.json +55 -0
  271. package/src/registry/patterns/comparison-panel.json +27 -0
  272. package/src/registry/patterns/component-showcase.json +24 -0
  273. package/src/registry/patterns/contact-form.json +31 -0
  274. package/src/registry/patterns/cta-section.json +20 -0
  275. package/src/registry/patterns/data-table.json +37 -0
  276. package/src/registry/patterns/detail-header.json +83 -0
  277. package/src/registry/patterns/detail-panel.json +27 -0
  278. package/src/registry/patterns/explorer-shell.json +22 -0
  279. package/src/registry/patterns/filter-bar.json +33 -0
  280. package/src/registry/patterns/filter-sidebar.json +27 -0
  281. package/src/registry/patterns/form-sections.json +110 -0
  282. package/src/registry/patterns/goal-tracker.json +27 -0
  283. package/src/registry/patterns/hero.json +107 -0
  284. package/src/registry/patterns/index.json +47 -0
  285. package/src/registry/patterns/kpi-grid.json +36 -0
  286. package/src/registry/patterns/media-gallery.json +20 -0
  287. package/src/registry/patterns/order-history.json +20 -0
  288. package/src/registry/patterns/pagination.json +19 -0
  289. package/src/registry/patterns/photo-to-recipe.json +36 -0
  290. package/src/registry/patterns/pipeline-tracker.json +28 -0
  291. package/src/registry/patterns/post-list.json +27 -0
  292. package/src/registry/patterns/pricing-table.json +32 -0
  293. package/src/registry/patterns/scorecard.json +28 -0
  294. package/src/registry/patterns/search-bar.json +20 -0
  295. package/src/registry/patterns/specimen-grid.json +19 -0
  296. package/src/registry/patterns/stat-card.json +55 -0
  297. package/src/registry/patterns/stats-bar.json +55 -0
  298. package/src/registry/patterns/steps-card.json +55 -0
  299. package/src/registry/patterns/table-of-contents.json +19 -0
  300. package/src/registry/patterns/testimonials.json +21 -0
  301. package/src/registry/patterns/timeline.json +27 -0
  302. package/src/registry/patterns/token-inspector.json +21 -0
  303. package/src/registry/patterns/wizard.json +27 -0
  304. package/src/registry/recipe-auradecantism.json +69 -0
  305. package/src/registry/recipe-clean.json +65 -0
  306. package/src/registry/recipe-command-center.json +78 -0
  307. package/src/registry/router.json +73 -0
  308. package/src/registry/schema/README.md +197 -0
  309. package/src/registry/skeletons.json +259 -0
  310. package/src/registry/state.json +137 -0
  311. package/src/registry/tokens.json +40 -0
  312. package/src/router/hash.js +17 -0
  313. package/src/router/history.js +18 -0
  314. package/src/router/index.js +598 -0
  315. package/src/ssr/index.js +922 -0
  316. package/src/state/arrays.js +181 -0
  317. package/src/state/devtools.js +647 -0
  318. package/src/state/index.js +498 -0
  319. package/src/state/middleware.js +288 -0
  320. package/src/state/scheduler.js +206 -0
  321. package/src/state/store.js +300 -0
  322. package/src/tags/index.js +19 -0
  323. package/src/tannins/auth.js +396 -0
  324. package/src/test/dom.js +352 -0
  325. package/src/test/index.js +62 -0
  326. package/src/test/state.js +306 -0
  327. package/tools/a11y-audit.js +487 -0
  328. package/tools/analyzer.js +315 -0
  329. package/tools/audit.js +706 -0
  330. package/tools/builder.js +1422 -0
  331. package/tools/css-extract.js +188 -0
  332. package/tools/dev-server.js +316 -0
  333. package/tools/dts-gen.js +1260 -0
  334. package/tools/figma-components.js +329 -0
  335. package/tools/figma-patterns.js +516 -0
  336. package/tools/figma-plugin/code.js +453 -0
  337. package/tools/figma-plugin/manifest.json +14 -0
  338. package/tools/figma-plugin/ui.html +268 -0
  339. package/tools/figma-render.js +293 -0
  340. package/tools/figma-tokens.js +712 -0
  341. package/tools/figma-upload.js +318 -0
  342. package/tools/generate.js +738 -0
  343. package/tools/icons.js +133 -0
  344. package/tools/init-templates.js +265 -0
  345. package/tools/install-hooks.sh +5 -0
  346. package/tools/migrations/0.5.0.js +53 -0
  347. package/tools/migrations/0.6.0.js +95 -0
  348. package/tools/minify.js +170 -0
  349. package/tools/pre-commit +4 -0
  350. package/tools/registry.js +662 -0
  351. package/tools/reset-playground.js +61 -0
  352. package/tools/starter-templates/content-site/app.js +49 -0
  353. package/tools/starter-templates/content-site/essence.js +19 -0
  354. package/tools/starter-templates/content-site/pages.js +31 -0
  355. package/tools/starter-templates/ecommerce/app.js +50 -0
  356. package/tools/starter-templates/ecommerce/essence.js +19 -0
  357. package/tools/starter-templates/ecommerce/pages.js +31 -0
  358. package/tools/starter-templates/landing-page/app.js +38 -0
  359. package/tools/starter-templates/landing-page/essence.js +18 -0
  360. package/tools/starter-templates/landing-page/pages.js +21 -0
  361. package/tools/starter-templates/portfolio/app.js +45 -0
  362. package/tools/starter-templates/portfolio/essence.js +19 -0
  363. package/tools/starter-templates/portfolio/pages.js +33 -0
  364. package/tools/starter-templates/saas-dashboard/app.js +70 -0
  365. package/tools/starter-templates/saas-dashboard/essence.js +19 -0
  366. package/tools/starter-templates/saas-dashboard/pages.js +31 -0
  367. package/tools/verify-pack.js +203 -0
  368. package/types/chart.d.ts +77 -0
  369. package/types/components.d.ts +587 -0
  370. package/types/core.d.ts +89 -0
  371. package/types/css.d.ts +149 -0
  372. package/types/data.d.ts +238 -0
  373. package/types/form.d.ts +164 -0
  374. package/types/i18n.d.ts +51 -0
  375. package/types/icons.d.ts +27 -0
  376. package/types/index.d.ts +13 -0
  377. package/types/router.d.ts +116 -0
  378. package/types/ssr.d.ts +102 -0
  379. package/types/state.d.ts +83 -0
  380. package/types/tags.d.ts +62 -0
  381. package/types/tannins.d.ts +63 -0
  382. package/types/test.d.ts +48 -0
@@ -0,0 +1,194 @@
1
+ # State Module Reference
2
+
3
+ `import { createSignal, createEffect, createMemo, createStore, batch, createContext, createSelector, createDeferred, createHistory, useLocalStorage, untrack, peek, createRoot, getOwner, runWithOwner, onError, on } from 'decantr/state';`
4
+
5
+ ## What's New (v0.5.0)
6
+
7
+ | Feature | Description | Cross-ref |
8
+ |---------|-------------|-----------|
9
+ | `createRoot` | Independent reactive scope with disposal | §createRoot |
10
+ | `getOwner` / `runWithOwner` | Ownership tree introspection and transfer | §Ownership |
11
+ | `onError` | Error boundaries in the reactive graph | §Error Boundaries |
12
+ | `on()` | Explicit dependency tracking | §on |
13
+ | Dependency cleanup | Effects auto-remove from old signal subscriber sets on re-run | Automatic |
14
+ | Topological flush | Diamond-problem fix — effects sorted by level before flush | Automatic |
15
+ | `createResource` **removed** | Replaced by `createQuery` in `decantr/data` | `reference/state-data.md` |
16
+
17
+ ## createSignal(initial)
18
+
19
+ Returns `[getter, setter]` tuple. Getter auto-tracks in effects/memos. Setter accepts value or updater function.
20
+
21
+ | Call | Behavior |
22
+ |------|----------|
23
+ | `setter(5)` | Set value to `5` |
24
+ | `setter(prev => prev + 1)` | Update from previous value |
25
+
26
+ Skips notification if new value is identical (`Object.is`).
27
+
28
+ ## createEffect(fn)
29
+
30
+ Runs `fn` immediately, auto-tracks all signal reads inside. Re-runs when any tracked signal changes. Returns `dispose()` function.
31
+
32
+ | Detail | Behavior |
33
+ |--------|----------|
34
+ | Auto-tracking | Reads during `fn` execution subscribe the effect |
35
+ | Dependency cleanup | On re-run, effect removes itself from old signal subscriber sets before re-tracking |
36
+ | Cleanup | If `fn` returns a function, it runs before next execution and on dispose |
37
+ | Dispose | `const dispose = createEffect(fn); dispose();` stops all future runs |
38
+ | Batching | During `batch()`, effects are deferred to topological flush |
39
+ | Error handling | Errors propagate up the ownership tree to nearest `onError` handler |
40
+
41
+ ## createMemo(fn)
42
+
43
+ Cached derived computation. Returns a getter. Recomputes lazily when dependencies change. Tracks reads like a signal — effects depending on the memo re-run only when the memo's value changes.
44
+
45
+ ```js
46
+ const [a, setA] = createSignal(1);
47
+ const double = createMemo(() => a() * 2);
48
+ double(); // 2
49
+ ```
50
+
51
+ ## createStore(initialValue)
52
+
53
+ Proxy-wrapped object with per-property reactive tracking. Reading a property inside an effect subscribes to that property. Writing a property notifies only subscribers of that specific key.
54
+
55
+ | Detail | Behavior |
56
+ |--------|----------|
57
+ | Tracking granularity | Per top-level property (not deep — see `decantr/state/store` for deep stores) |
58
+ | Identity check | Skips notification on `Object.is` equality |
59
+ | Return value | The proxy itself (mutate in place) |
60
+
61
+ ## batch(fn)
62
+
63
+ Defers all effect runs until `fn` completes. Supports nesting — flush happens when outermost `batch` exits. Flush uses topological ordering.
64
+
65
+ ```js
66
+ batch(() => {
67
+ setA(1);
68
+ setB(2); // effects run once after both updates
69
+ });
70
+ ```
71
+
72
+ ## createRoot(fn)
73
+
74
+ Create an independent reactive scope. `fn` receives a `dispose` function. All effects/memos created inside are owned by this root and disposed when `dispose()` is called.
75
+
76
+ ```js
77
+ const result = createRoot(dispose => {
78
+ const [count, setCount] = createSignal(0);
79
+ createEffect(() => console.log(count()));
80
+ // dispose() cleans up effect and all children
81
+ return { count, setCount, dispose };
82
+ });
83
+ ```
84
+
85
+ ## getOwner() / runWithOwner(owner, fn)
86
+
87
+ Introspect and transfer ownership context. Useful for effects created outside the normal component tree (e.g., in setTimeout, event handlers).
88
+
89
+ ```js
90
+ const owner = getOwner(); // capture in sync context
91
+ setTimeout(() => {
92
+ runWithOwner(owner, () => {
93
+ createEffect(() => { /* properly owned */ });
94
+ });
95
+ }, 1000);
96
+ ```
97
+
98
+ ## onError(handler)
99
+
100
+ Register an error handler on the current owner. When an effect throws, the error walks up the ownership tree to find the nearest handler.
101
+
102
+ ```js
103
+ createRoot(() => {
104
+ onError(err => console.error('Caught:', err));
105
+ createEffect(() => { throw new Error('boom'); }); // caught by handler
106
+ });
107
+ ```
108
+
109
+ ## on(deps, fn, options?)
110
+
111
+ Explicit dependency tracking. Reads `deps` inside tracking context, calls `fn` inside `untrack()`. Useful when you need to read a signal inside an effect without subscribing to it.
112
+
113
+ | Option | Description |
114
+ |--------|-------------|
115
+ | `defer` | If `true`, skip initial run (default: `false`) |
116
+
117
+ ```js
118
+ const [count, setCount] = createSignal(0);
119
+ const [name] = createSignal('World');
120
+
121
+ // Only re-runs when count changes, not when name changes
122
+ on(count, (value, prev) => {
123
+ console.log(`count: ${prev} → ${value}, name: ${name()}`);
124
+ });
125
+ ```
126
+
127
+ Supports array of dependencies:
128
+ ```js
129
+ on([a, b], ([aVal, bVal], [prevA, prevB]) => { ... });
130
+ ```
131
+
132
+ ## createContext(defaultValue?)
133
+
134
+ Dependency injection via Provider/consume pattern. Returns `{ Provider, consume }`.
135
+
136
+ | Method | Signature | Description |
137
+ |--------|-----------|-------------|
138
+ | `Provider` | `(value: T) => () => void` | Sets context value, returns restore function |
139
+ | `consume` | `() => T` | Reads current value (or `defaultValue`) |
140
+
141
+ ```js
142
+ const ThemeCtx = createContext('light');
143
+ const restore = ThemeCtx.Provider('dark');
144
+ ThemeCtx.consume(); // 'dark'
145
+ restore(); // restores previous value
146
+ ```
147
+
148
+ ## createSelector(source)
149
+
150
+ Per-key memoization for efficient list highlighting. Returns `isSelected(key)` — a reactive check that only notifies when a specific key's match status changes.
151
+
152
+ ```js
153
+ const [selected, setSelected] = createSignal('a');
154
+ const isSelected = createSelector(selected);
155
+ // In a list item: isSelected('a') returns true, re-runs only when 'a' gains/loses selection
156
+ ```
157
+
158
+ ## createDeferred(fn)
159
+
160
+ Like `createMemo` but lazy-initialized — does not compute until the returned getter is first called. Subsequent reads use cached value until dependencies change, then recomputes on next read.
161
+
162
+ ## createHistory(signal, options?)
163
+
164
+ Undo/redo history tracking for a signal.
165
+
166
+ | Param | Type | Description |
167
+ |-------|------|-------------|
168
+ | `signal` | `[getter, setter]` | Signal tuple from `createSignal` |
169
+ | `options.maxLength` | `number` | Max undo depth (default: `100`) |
170
+
171
+ | Key | Type | Description |
172
+ |-----|------|-------------|
173
+ | `canUndo` | `() => boolean` | Signal getter |
174
+ | `canRedo` | `() => boolean` | Signal getter |
175
+ | `undo` | `() => void` | Restore previous value |
176
+ | `redo` | `() => void` | Re-apply undone value |
177
+ | `clear` | `() => void` | Reset history to current value |
178
+
179
+ ## useLocalStorage(key, initial)
180
+
181
+ Signal backed by `localStorage` with JSON serialization. Returns `[getter, setter]` — same API as `createSignal`.
182
+
183
+ ## untrack(fn) / peek(getter)
184
+
185
+ Read signals without subscribing the current effect.
186
+
187
+ | Function | Use case |
188
+ |----------|----------|
189
+ | `untrack(fn)` | Run `fn` with tracking disabled |
190
+ | `peek(getter)` | Alias for `untrack(getter)` |
191
+
192
+ ---
193
+
194
+ **See also:** `reference/state-data.md`, `reference/component-lifecycle.md`, `reference/router.md`
@@ -0,0 +1,110 @@
1
+ # Style + Mode System
2
+
3
+ Decantr uses an orthogonal **style x mode** architecture. Visual personality (style) is independent from color mode (light/dark/auto).
4
+
5
+ ## Styles (Visual Personality)
6
+
7
+ | Style | Description | Personality |
8
+ |-------|-------------|-------------|
9
+ | auradecantism | **(default)** Dark glass aesthetic — vibrant purple/cyan/pink palette, mesh gradients, luminous glow, frosted surfaces | radius:pill, elevation:glass, motion:bouncy, borders:thin, density:comfortable, gradient:vivid |
10
+ | clean | Modern minimal — rounded corners, subtle shadows, smooth motion | radius:rounded, elevation:subtle, motion:smooth, borders:thin, density:comfortable, gradient:none |
11
+ | retro | Neobrutalism — sharp corners, offset shadows, bold borders | radius:sharp, elevation:brutalist, motion:snappy, borders:bold, density:comfortable, gradient:none |
12
+ | glassmorphism | Frosted glass — translucent surfaces, vivid gradients, bouncy motion | radius:pill, elevation:glass, motion:bouncy, borders:thin, density:comfortable, gradient:vivid |
13
+ | command-center | HUD/radar monochromatic — dark operational panels, beveled frames, scanlines, monospace typography | radius:sharp, elevation:flat, motion:snappy, borders:bold, density:compact, gradient:none, palette:monochrome |
14
+
15
+ ## Modes
16
+
17
+ | Mode | Behavior |
18
+ |------|----------|
19
+ | light | Light color scheme |
20
+ | dark | Dark color scheme |
21
+ | auto | Tracks system `prefers-color-scheme`, listens for changes |
22
+
23
+ ## Seed-Derived Token System
24
+
25
+ 10 seed colors + 6 personality traits are algorithmically expanded into **280+ CSS custom properties** by `src/css/derive.js`. No manual color definitions needed — everything is computed.
26
+
27
+ **Seed colors:** primary, accent, tertiary, neutral, success, warning, error, info, bg, bgDark
28
+ **Personality traits:** radius (sharp/rounded/pill), elevation (flat/subtle/raised/glass/brutalist), motion (instant/snappy/smooth/bouncy), borders (none/thin/bold), density (compact/comfortable/spacious), gradient (none/subtle/vivid/mesh)
29
+
30
+ ## Custom Styles
31
+
32
+ ```javascript
33
+ registerStyle({
34
+ id: 'my-style',
35
+ name: 'My Style',
36
+ seed: { primary: '#6366f1', accent: '#ec4899', bg: '#ffffff', bgDark: '#0a0a0a' },
37
+ personality: { radius: 'pill', elevation: 'glass', motion: 'bouncy', borders: 'none' },
38
+ typography: { '--d-fw-heading': '800' }, // optional overrides
39
+ overrides: { light: {}, dark: {} }, // optional per-mode token overrides
40
+ components: '', // optional component CSS
41
+ });
42
+ ```
43
+
44
+ ## Shape API
45
+
46
+ Shapes control border-radius personality independently from the style. Available shapes: `sharp`, `rounded`, `pill`.
47
+
48
+ ```javascript
49
+ setShape('pill'); // All components use pill radius
50
+ getShape(); // 'pill'
51
+ getShapeList(); // ['sharp', 'rounded', 'pill']
52
+ ```
53
+
54
+ Shapes override the style's default radius. The command-center style defaults to `sharp`; glassmorphism defaults to `pill`.
55
+
56
+ ## Colorblind Mode
57
+
58
+ Colorblind mode is an orthogonal axis alongside style, mode, and shape: `Style x Mode x Shape x ColorblindMode`.
59
+
60
+ ```javascript
61
+ setColorblindMode('protanopia'); // Red-green CVD safety
62
+ setColorblindMode('deuteranopia'); // Red-green CVD safety (same shifts)
63
+ setColorblindMode('tritanopia'); // Blue-yellow CVD safety
64
+ setColorblindMode('off'); // Default (no transformation)
65
+ getColorblindMode(); // Signal getter
66
+ ```
67
+
68
+ **Architecture:** Seeds are transformed BEFORE `derive()` processes them, so all derived tokens (hover, active, subtle, border, chart, gradient) automatically adapt. Chart tokens are replaced with Wong/Okabe-Ito adapted palettes for maximum CVD safety.
69
+
70
+ **Seed shifts (protanopia/deuteranopia):** error red -> magenta (OKLCH H ~345), success green -> teal (OKLCH H ~190). Primary/accent/tertiary shifted if in red or green hue zones.
71
+
72
+ **Seed shifts (tritanopia):** info blue -> teal (OKLCH H ~170), warning yellow -> orange (OKLCH H ~50). Primary shifted if in blue hue zone.
73
+
74
+ `resetStyles()` resets colorblind mode to `'off'`. See `reference/color-guidelines.md` for full documentation.
75
+
76
+ ## OKLCH Color Space
77
+
78
+ All color math in `derive.js` uses **OKLCH** (perceptually uniform color space) instead of HSL. This means:
79
+ - `lighten(hex, amount)` and `darken(hex, amount)` adjust the OKLCH L channel
80
+ - `mixColors(hex1, hex2, weight)` interpolates in OKLCH space with short-arc hue blending
81
+ - `rotateHue(hex, degrees)` rotates the OKLCH H channel
82
+ - Hover states look more consistent across all 7 palette roles (same perceived brightness shift regardless of hue)
83
+ - `adjustForContrast()` converges faster due to perceptual uniformity
84
+
85
+ Internal exports for testing/advanced use: `rgbToOklch(r,g,b)`, `oklchToRgb(L,C,H)`, `gamutMap(L,C,H)`.
86
+
87
+ ## Monochrome Palette
88
+
89
+ The `palette: 'monochrome'` personality trait (used by command-center) derives all 7 role colors from a single primary hue. All shifts stay within ±20° of base hue; distinguishability comes via lightness/saturation. WCAG AA validated via `validateContrast()`.
90
+
91
+ ## Backward Compatibility
92
+
93
+ `setTheme()`, `getTheme()`, `registerTheme()` are backward-compatible wrappers around the Style+Mode API. Legacy `--c0`–`--c9` color variables and `_fg0`–`_fg9` atoms have been removed — use semantic atoms (`_fgfg`, `_fgmutedfg`, `_fgprimary`, etc.) instead.
94
+
95
+ ## Build-Time Style Elimination
96
+
97
+ At build time, unused style modules are automatically detected and removed from the bundle. The build pipeline scans user code for `setStyle()` and `setTheme()` calls, and checks `decantr.essence.json` and `decantr.config.json` for style references. Only the default style (auradecantism) and explicitly referenced styles are shipped. For a default app using only auradecantism, this eliminates 4 unused styles and saves ~17 KB raw.
98
+
99
+ See `reference/build-tooling.md` for full details on the detection and elimination pipeline.
100
+
101
+ ## Key Files
102
+
103
+ - `src/css/derive.js` — Color math, personality presets, main `derive()` function
104
+ - `src/css/styles/auradecantism.js` / `clean.js` / `retro.js` / `glassmorphism.js` / `command-center.js` — Style definitions
105
+ - `src/css/theme-registry.js` — State management, DOM injection, public API
106
+ - `src/css/index.js` — Public CSS module exports
107
+
108
+ ---
109
+
110
+ **See also:** `reference/tokens.md`, `reference/decantation-process.md`, `reference/atoms.md`