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,517 @@
1
+ # Atomic CSS Reference
2
+
3
+ All atoms are prefixed with `_` (underscore) for namespace safety — zero conflicts with Tailwind, Bootstrap, or any CSS framework. Every decantr atom starts with `_`.
4
+
5
+ All atoms are available via `css()`. Example: `css('_grid _gc3 _gap4 _p6 _ctr')`.
6
+
7
+ ## Spacing (_p, _m, _gap — scale 0-12 + 14,16,20,24,32,40,48,56,64)
8
+
9
+ > For decision logic on which spacing atoms to use, see `reference/spatial-guidelines.md` §2 Spatial Taxonomy and §18 Quick Reference Decision Table.
10
+ | Prefix | Property | Example |
11
+ |--------|----------|---------|
12
+ | `_p` | padding | `_p4` -> `1rem` |
13
+ | `_px/_py` | padding-inline/block | `_px2` -> `0.5rem` |
14
+ | `_pt/_pr/_pb/_pl` | padding sides | `_pt1` -> `0.25rem` |
15
+ | `_m` | margin | `_m4` -> `1rem` |
16
+ | `_mx/_my` | margin-inline/block | `_mx2` -> `0.5rem` |
17
+ | `_mt/_mr/_mb/_ml` | margin sides | `_mt1` -> `0.25rem` |
18
+ | `_gap/_gx/_gy` | gap/column-gap/row-gap | `_gap4` -> `1rem` |
19
+
20
+ ## Negative Margins (scale 1-12 + 14,16,20,24,32)
21
+ `_-m2` -> `margin:-0.5rem`, `_-mt4` -> `margin-top:-1rem`, `_-mx1`, `_-my3`, `_-mr2`, `_-mb1`, `_-ml4`
22
+
23
+ ## Auto Margins
24
+ `_ma` (margin:auto), `_mxa` (margin-inline:auto), `_mya` (margin-block:auto), `_mta`, `_mra`, `_mba`, `_mla`
25
+
26
+ ## Width/Height (scale 0-12 + extended + keywords)
27
+ | Atom | Output |
28
+ |------|--------|
29
+ | `_w4/_h4` | width/height: 1rem |
30
+ | `_wfull/_hfull` | 100% |
31
+ | `_wscreen` | width:100vw |
32
+ | `_hscreen` | height:100vh |
33
+ | `_wauto/_hauto` | auto |
34
+ | `_wfit/_hfit` | fit-content |
35
+ | `_wmin/_wmax` | min-content/max-content |
36
+ | `_hmin/_hmax` | min-content/max-content |
37
+ | `_mw4/_mh4` | max-width/max-height |
38
+ | `_mwmin/_mwmax` | max-width: min/max-content |
39
+ | `_mhmin/_mhmax` | max-height: min/max-content |
40
+
41
+ ## Min-Width/Height (scale 0-12 + extended + keywords)
42
+ `_minw0`-`_minw64`, `_minwfull`, `_minwscreen` (100vw), `_minwfit`, `_minwmin`, `_minwmax`
43
+ `_minh0`-`_minh64`, `_minhfull`, `_minhscreen` (100vh), `_minhfit`, `_minhmin`, `_minhmax`
44
+
45
+ ## Display
46
+ `_block`, `_inline`, `_flex`, `_grid`, `_none`, `_contents`, `_iflex`, `_igrid`
47
+
48
+ ## Flexbox
49
+ | Atom | Output |
50
+ |------|--------|
51
+ | `_col/_row` | flex-direction |
52
+ | `_colr/_rowr` | column-reverse/row-reverse |
53
+ | `_wrap/_nowrap/_wrapr` | flex-wrap |
54
+ | `_grow/_grow0` | flex-grow: 1/0 |
55
+ | `_shrink/_shrink0` | flex-shrink: 1/0 |
56
+ | `_flex1` | flex: 1 1 0% |
57
+ | `_flexauto` | flex: 1 1 auto |
58
+ | `_flexnone` | flex: none |
59
+ | `_flexinit` | flex: 0 1 auto |
60
+
61
+ ## Flex-Basis (scale 0-12 + extended + percentages)
62
+ `_basis0`-`_basis12`, `_basis14`-`_basis64`, `_basisa` (auto)
63
+ `_basis25` (25%), `_basis33` (33.333%), `_basis50` (50%), `_basis66` (66.667%), `_basis75` (75%), `_basisfull` (100%)
64
+
65
+ ## Order
66
+ `_ord0`-`_ord12`, `_ord-1` (-1), `_ordfirst` (-9999), `_ordlast` (9999)
67
+
68
+ ## Alignment
69
+ | Atom | Property | Value |
70
+ |------|----------|-------|
71
+ | `_center` | align-items + justify-content | center |
72
+ | `_aic/_ais/_aifs/_aife/_aibs` | align-items | center/stretch/flex-start/flex-end/baseline |
73
+ | `_jcc/_jcsb/_jcsa/_jcse/_jcfs/_jcfe` | justify-content | center/space-between/around/evenly/flex-start/flex-end |
74
+ | `_acc/_acsb/_acsa/_acse/_acfs/_acfe/_acs` | align-content | center/space-between/around/evenly/flex-start/flex-end/stretch |
75
+ | `_asc/_ass/_asfs/_asfe/_asa/_asbs` | align-self | center/stretch/flex-start/flex-end/auto/baseline |
76
+ | `_jic/_jis/_jifs/_jife` | justify-items | center/stretch/start/end |
77
+ | `_jsc/_jss/_jsfs/_jsfe/_jsa` | justify-self | center/stretch/start/end/auto |
78
+ | `_pic/_pis` | place-items | center/stretch |
79
+ | `_pcc/_pcse/_pcsb` | place-content | center/space-evenly/space-between |
80
+
81
+ ## Grid System
82
+
83
+ > For column count by content type and container width guidance, see `reference/spatial-guidelines.md` §14 Grid & Column System.
84
+
85
+ | Atom | Output |
86
+ |------|--------|
87
+ | `_gc1`-`_gc12` | grid-template-columns: repeat(N,minmax(0,1fr)) |
88
+ | `_gcnone` | grid-template-columns: none |
89
+ | `_gr1`-`_gr6` | grid-template-rows: repeat(N,minmax(0,1fr)) |
90
+ | `_grnone` | grid-template-rows: none |
91
+ | `_span1`-`_span12` | grid-column: span N/span N |
92
+ | `_spanfull` | grid-column: 1/-1 |
93
+ | `_rspan1`-`_rspan6` | grid-row: span N/span N |
94
+ | `_rspanfull` | grid-row: 1/-1 |
95
+ | `_gcs1`-`_gcs13` | grid-column-start |
96
+ | `_gce1`-`_gce13` | grid-column-end |
97
+ | `_grs1`-`_grs7` | grid-row-start |
98
+ | `_gre1`-`_gre7` | grid-row-end |
99
+ | `_gcaf160/200/220/250/280/300/320` | repeat(auto-fit,minmax(Npx,1fr)) |
100
+ | `_gcaf` | repeat(auto-fit,minmax(0,1fr)) |
101
+ | `_gcafl` | repeat(auto-fill,minmax(0,1fr)) |
102
+ | `_gflowr/_gflowc/_gflowd/_gflowrd/_gflowcd` | grid-auto-flow |
103
+ | `_gacfr/_gacmin/_gacmax` | grid-auto-columns |
104
+ | `_garfr/_garmin/_garmax` | grid-auto-rows |
105
+
106
+ ## Aspect Ratio
107
+ `_arsq` (1), `_ar169` (16/9), `_ar43` (4/3), `_ar219` (21/9), `_ar32` (3/2), `_ara` (auto)
108
+
109
+ ## Container Utilities
110
+ `_ctrsm` (640px), `_ctr` (960px), `_ctrlg` (1080px), `_ctrxl` (1280px), `_ctrfull` (100%) — all include margin-inline:auto
111
+
112
+ ## Overflow
113
+ `_ohidden`, `_oauto`, `_oscroll`, `_ovisible`
114
+ `_oxhidden`, `_oxauto`, `_oxscroll`, `_oyhidden`, `_oyauto`, `_oyscroll`
115
+
116
+ ## Text & Visibility
117
+ `_visible`, `_invisible`, `_wsnw` (nowrap), `_wsnormal`, `_wspre`, `_wsprewrap`
118
+ `_truncate` (overflow:hidden + text-overflow:ellipsis + white-space:nowrap)
119
+ `_clamp2`, `_clamp3` (line clamping via -webkit-line-clamp)
120
+
121
+ ## Line-Height
122
+ `_lh1` (1), `_lh1a`/`_lh125` (1.25), `_lh1b`/`_lh150` (1.5), `_lh175` (1.75), `_lh2` (2)
123
+
124
+ ## Typography
125
+ `_t10`-`_t48` (font-size, fixed rem), `_bold/_medium/_normal/_light` (weight), `_italic`, `_underline/_strike/_nounder`, `_upper/_lower/_cap`, `_tl/_tc/_tr`
126
+
127
+ ## Token-Backed Typography (theme-customizable)
128
+
129
+ > For typographic spatial rules (heading asymmetry, vertical rhythm), see `reference/spatial-guidelines.md` §8 Typographic Spatial System.
130
+ | Atom | CSS Output |
131
+ |------|-----------|
132
+ | `_textxs`-`_text4xl` | `font-size:var(--d-text-{size},{fallback})` — xs/sm/base/md/lg/xl/2xl/3xl/4xl |
133
+ | `_lhtight` | `line-height:var(--d-lh-tight,1.1)` |
134
+ | `_lhsnug` | `line-height:var(--d-lh-snug,1.25)` |
135
+ | `_lhnormal` | `line-height:var(--d-lh-normal,1.5)` |
136
+ | `_lhrelaxed` | `line-height:var(--d-lh-relaxed,1.6)` |
137
+ | `_lhloose` | `line-height:var(--d-lh-loose,1.75)` |
138
+ | `_fwheading` | `font-weight:var(--d-fw-heading,700)` |
139
+ | `_fwtitle` | `font-weight:var(--d-fw-title,600)` |
140
+ | `_lsheading` | `letter-spacing:var(--d-ls-heading,-0.025em)` |
141
+
142
+ Use `_text*`/`_lh*`/`_fw*` atoms in components for theme-customizable typography. Use `_t10`-`_t48` for fixed sizes that should not change per theme.
143
+
144
+ ## Typography Presets (compound atoms)
145
+
146
+ Bundles of size+weight+lineHeight+letterSpacing for common text roles. All token-backed with `var()` fallbacks — theme-customizable automatically (retro gets bolder headings, etc.).
147
+
148
+ | Atom | Size | Weight | Line Height | Extra |
149
+ |------|------|--------|-------------|-------|
150
+ | `_heading1` | `--d-text-4xl` | `--d-fw-heading` | `--d-lh-tight` | `--d-ls-heading` |
151
+ | `_heading2` | `--d-text-3xl` | `--d-fw-heading` | `--d-lh-tight` | `--d-ls-heading` |
152
+ | `_heading3` | `--d-text-2xl` | `--d-fw-heading` | `--d-lh-snug` | `--d-ls-heading` |
153
+ | `_heading4` | `--d-text-xl` | `--d-fw-title` | `--d-lh-snug` | — |
154
+ | `_heading5` | `--d-text-lg` | `--d-fw-title` | `--d-lh-snug` | — |
155
+ | `_heading6` | `--d-text-md` | `--d-fw-title` | `--d-lh-normal` | — |
156
+ | `_body` | `--d-text-base` | — | `--d-lh-normal` | — |
157
+ | `_bodylg` | `--d-text-md` | — | `--d-lh-relaxed` | — |
158
+ | `_caption` | `--d-text-sm` | — | `--d-lh-normal` | `color:--d-muted-fg` |
159
+ | `_label` | `--d-text-sm` | `--d-fw-medium` | `--d-lh-none` | — |
160
+ | `_overline` | `--d-text-xs` | `--d-fw-medium` | `--d-lh-none` | `uppercase; ls:0.08em` |
161
+
162
+ Usage: `h1({ class: css('_heading1') }, 'Page Title')` — one atom replaces 3-4 individual atoms.
163
+
164
+ ## Colors (Semantic)
165
+ **Palette roles**: `_bg{role}`, `_fg{role}`, `_bc{role}` — where role = `primary`, `accent`, `tertiary`, `success`, `warning`, `error`, `info`
166
+ **Subtle variants**: `_bg{role}sub`, `_fg{role}sub` (subtle bg/fg), `_bc{role}bdr` (role border)
167
+ **Foreground-on-base**: `_fg{role}on` (contrasting text on role background)
168
+ **Neutrals**: `_bgbg`, `_fgfg`, `_bgmuted`, `_fgmuted`, `_fgmutedfg`, `_bcborder`, `_bcstrong`
169
+ **Surfaces**: `_surface0`-`_surface3`, `_fgsurface0`-`_fgsurface3`, `_bcsurface0`-`_bcsurface3`
170
+ **Opacity**: `_bg{role}/N` (e.g. `_bgprimary/50`) — color-mix with transparency (0-100)
171
+
172
+ ### Color Decision Flow
173
+
174
+ | Intent | Atom | Token |
175
+ |--------|------|-------|
176
+ | Primary text | `_fgfg` | `--d-fg` |
177
+ | Muted/secondary text | `_fgmutedfg` | `--d-muted-fg` |
178
+ | Even more muted text | `_fgmuted` | `--d-muted` |
179
+ | Accent/brand text | `_fgprimary` | `--d-primary` |
180
+ | Page background | `_bgbg` | `--d-bg` |
181
+ | Muted background | `_bgmuted` | `--d-muted` |
182
+ | Primary action bg | `_bgprimary` | `--d-primary` |
183
+ | Surface card bg | `_surface0`–`_surface3` | `--d-surface-{0-3}` |
184
+ | Border default | `_bcborder` | `--d-border` |
185
+ | Border emphasis | `_bcstrong` | `--d-border-strong` |
186
+ | Error state | `_fgerror` / `_bgerror` | `--d-error` |
187
+ | Success state | `_fgsuccess` / `_bgsuccess` | `--d-success` |
188
+
189
+ ## Field Atoms
190
+
191
+ Unified field container atoms. Pair with field tokens for consistent form styling.
192
+
193
+ | Atom | Output |
194
+ |------|--------|
195
+ | `_field` | Field visual base — applies `--d-field-bg`, `--d-field-border`, `--d-field-radius`, border-width |
196
+ | `_fieldOutlined` | Outlined variant (alias for `_field`) — transparent bg, visible border |
197
+ | `_fieldFilled` | Filled variant — surface bg, transparent border |
198
+ | `_fieldGhost` | Ghost variant — transparent bg + border, shows border on focus |
199
+
200
+ ## Interactive State Atoms
201
+
202
+ Semantic background/foreground atoms for item selection and hover states.
203
+
204
+ | Atom | Output |
205
+ |------|--------|
206
+ | `_hoverBg` | `background:var(--d-item-hover-bg)` — hover background for list items, options, rows |
207
+ | `_activeBg` | `background:var(--d-item-active-bg)` — active/pressed item background |
208
+ | `_selectedBg` | `background:var(--d-selected-bg)` — selected item background |
209
+ | `_selectedFg` | `color:var(--d-selected-fg)` — selected item foreground |
210
+
211
+ ## Semantic Opacity Atoms
212
+
213
+ | Atom | Output |
214
+ |------|--------|
215
+ | `_disabled` | `opacity:var(--d-disabled-opacity);cursor:not-allowed;pointer-events:none` — disabled state |
216
+
217
+ ## Layout Atoms
218
+
219
+ | Atom | Output |
220
+ |------|--------|
221
+ | `_proseWidth` | `max-width:var(--d-prose-width,75ch)` — optimal reading line length |
222
+
223
+ ## Atom Resolution
224
+
225
+ Atoms are resolved algorithmically by `resolveAtomDecl()` in `src/css/atoms.js` (rewritten from a 665-line imperative Map to a 548-line algorithmic resolver). The resolution order is:
226
+
227
+ 1. **ALIASES** — long-form names to canonical terse atoms (`_gridCols4` → `_gc4`, etc.)
228
+ 2. **DIRECT** — known fixed atoms looked up by exact name
229
+ 3. **Algorithmic patterns** — spacing scales, grid columns, typography sizes, colors, etc. computed from naming conventions
230
+ 4. **RESIDUAL** — remaining one-off atoms that don't fit algorithmic patterns
231
+
232
+ The `css()` API is unchanged. In **production builds** with static CSS extraction enabled, all atoms are pre-resolved at build time and `css()` becomes a lightweight passthrough (~673 bytes) that only converts `_group` to `d-group`, `_peer` to `d-peer`, and joins class names. The `atoms.js` and `runtime.js` modules are removed entirely from the bundle. If `define()` or dynamic `css()` patterns are detected, the full runtime is preserved as a fallback.
233
+
234
+ ## Aliases
235
+ Long-form names resolve to canonical terse atoms: `_gridCols4` → `_gc4`, `_noDecoration` → `_nounder`, `_border` → `_b1`, `_borderColor` → `_bcborder`, `_radiusFull` → `_rfull`, `_radius0`-`_radius8` → `_r0`-`_r8`
236
+
237
+ ## Position
238
+ `_relative/_absolute/_fixed/_sticky` (or `_rel/_abs`), `_top0/_right0/_bottom0/_left0/_inset0`
239
+
240
+ ## Borders
241
+ `_b0/_b1/_b2`, `_r0`-`_r8` (border-radius), `_rfull` (9999px), `_rcircle` (50%)
242
+
243
+ ### Radius Decision Flow
244
+
245
+ | Element | Atom | Rationale |
246
+ |---------|------|-----------|
247
+ | Buttons, inputs | `_r2`–`_r3` | Standard interactive controls |
248
+ | Cards, panels | `_r3`–`_r4` | Content containers |
249
+ | Avatars, tags | `_rfull` | Circular/pill shapes |
250
+ | Table cells | `_r2` | Subtle rounding |
251
+ | Modals, dialogs | `_r4` | Prominent containers |
252
+ | Sharp/no radius | `_r0` | Data-dense, technical UIs |
253
+
254
+ ## Opacity, Transitions, Z-index, Shadow, Cursor
255
+ `_op0`-`_op10`, `_trans/_transfast/_transslow/_transnone`, `_z0/_z10/_z20/_z30/_z40/_z50`
256
+ `_shadow/_shadowmd/_shadowlg/_shadowno`, `_pointer/_grab`
257
+
258
+ ### Arbitrary Transition Syntax
259
+
260
+ Use bracket notation `_trans[...]` for custom transitions. Underscores in the value are converted to spaces:
261
+
262
+ ```js
263
+ css('_trans[color_0.15s_ease]') // transition: color 0.15s ease
264
+ css('_trans[opacity_0.2s_ease-in-out]') // transition: opacity 0.2s ease-in-out
265
+ css('_trans[transform_0.3s_cubic-bezier(0.4,0,0.2,1)]') // custom easing
266
+ ```
267
+
268
+ This uses the `trans` arbitrary value prefix (mapped to `transition` in `ARB_PROPS`). Prefer `_trans` (all 0.2s ease) for standard transitions and `_trans[...]` only when you need to target specific properties or non-standard durations.
269
+
270
+ ---
271
+
272
+ ## Composable Gradient System
273
+
274
+ Build gradients by combining direction + from + via + to atoms. Uses CSS variable composition.
275
+
276
+ ```js
277
+ css('_gradBR _fromPrimary _toAccent') // bottom-right, primary → accent
278
+ css('_gradR _fromPrimary _viaSuccess _toTransparent') // right, with via stop
279
+ ```
280
+
281
+ **Direction atoms:** `_gradR`, `_gradL`, `_gradT`, `_gradB`, `_gradBR`, `_gradBL`, `_gradTR`, `_gradTL`
282
+
283
+ **From atoms** (set start color): `_fromPrimary`, `_fromAccent`, `_fromTertiary`, `_fromSuccess`, `_fromWarning`, `_fromError`, `_fromInfo`, `_fromBg`, `_fromSurface1`, `_fromTransparent`
284
+
285
+ **Via atoms** (set middle color): `_viaPrimary`, `_viaAccent`, `_viaTertiary`, `_viaSuccess`, `_viaWarning`, `_viaError`, `_viaInfo`, `_viaBg`, `_viaSurface1`, `_viaTransparent`
286
+
287
+ **To atoms** (set end color): `_toPrimary`, `_toAccent`, `_toTertiary`, `_toSuccess`, `_toWarning`, `_toError`, `_toInfo`, `_toBg`, `_toSurface1`, `_toTransparent`
288
+
289
+ Works with responsive: `css('_sm:gradBR')`. Works with container queries: `css('_cq640:gradR')`.
290
+
291
+ ## Opacity Modifiers
292
+
293
+ Append `/N` to any color atom for alpha transparency. Uses `color-mix()` (96%+ browser support).
294
+
295
+ ```js
296
+ css('_bgprimary/50') // background at 50% opacity
297
+ css('_fgaccent/30') // text at 30% opacity
298
+ css('_bcborder/80') // border at 80% opacity
299
+ css('_sm:bgprimary/20') // responsive: 20% at sm+
300
+ ```
301
+
302
+ Valid opacities: 5, 10, 15, 20, 25, 30, 40, 50, 60, 70, 75, 80, 90, 95.
303
+
304
+ Works with all color atoms (`_bg*`, `_fg*`, `_bc*`), responsive prefixes, and container queries.
305
+
306
+ ## Group/Peer State Modifiers
307
+
308
+ Style children based on parent state, or siblings based on peer state.
309
+
310
+ ```js
311
+ // Group: parent hover affects children
312
+ div({ class: css('_group') },
313
+ span({ class: css('_fgmuted _gh:fgprimary _trans') }, 'Turns primary on parent hover')
314
+ )
315
+
316
+ // Peer: sibling state affects next sibling
317
+ input({ class: css('_peer'), type: 'checkbox' }),
318
+ label({ class: css('_fgmuted _pf:fgprimary') }, 'Turns primary when input focused')
319
+ ```
320
+
321
+ **Markers:** `_group` → outputs `d-group`, `_peer` → outputs `d-peer`
322
+
323
+ | Prefix | State | Selector Pattern |
324
+ |--------|-------|-----------------|
325
+ | `_gh:` | group-hover | `.d-group:hover .cls` |
326
+ | `_gf:` | group-focus-within | `.d-group:focus-within .cls` |
327
+ | `_ga:` | group-active | `.d-group:active .cls` |
328
+ | `_ph:` | peer-hover | `.d-peer:hover ~ .cls` |
329
+ | `_pf:` | peer-focus | `.d-peer:focus ~ .cls` |
330
+ | `_pa:` | peer-active | `.d-peer:active ~ .cls` |
331
+
332
+ Works with any atom: `_gh:elev2`, `_gh:bgprimary/50`, `_gf:bcprimary`.
333
+
334
+ ## Responsive Prefixes (Mobile-First)
335
+
336
+ All atoms support responsive prefixes. Syntax: `_bp:atom`. Below the breakpoint, the base atom applies; at and above it, the prefixed atom takes over.
337
+
338
+ | Prefix | Min-Width | Example |
339
+ |--------|-----------|---------|
340
+ | `_sm:` | 640px | `css('_gc1 _sm:gc2')` — 1 col, 2 at sm+ |
341
+ | `_md:` | 768px | `css('_p4 _md:p8')` — p4 default, p8 at md+ |
342
+ | `_lg:` | 1024px | `css('_col _lg:row')` — column default, row at lg+ |
343
+ | `_xl:` | 1280px | `css('_ctr _xl:ctrxl')` — 960px default, 1280px at xl+ |
344
+
345
+ Works with all atoms including arbitrary values: `css('_sm:w[512px]')`, color opacity: `css('_sm:bgprimary/20')`, gradients: `css('_sm:gradBR')`.
346
+
347
+ ## Container Query Prefixes
348
+
349
+ Style children based on container width, not viewport. Syntax: `_cqN:atom` where N is the min-width in pixels.
350
+
351
+ | Prefix | Min-Width | Example |
352
+ |--------|-----------|---------|
353
+ | `_cq320:` | 320px | `css('_cq320:gc2')` |
354
+ | `_cq480:` | 480px | `css('_cq480:gc3')` |
355
+ | `_cq640:` | 640px | `css('_cq640:gc4')` |
356
+ | `_cq768:` | 768px | `css('_cq768:row')` |
357
+ | `_cq1024:` | 1024px | `css('_cq1024:gc6')` |
358
+
359
+ Only these 5 widths are valid. Parent must have `container-type: inline-size` (use `_ctype[inline-size]` or set via CSS).
360
+
361
+ ## Arbitrary Values
362
+
363
+ Escape hatch for one-off values without leaving utility-first flow.
364
+
365
+ ```js
366
+ css('_w[512px]') // width:512px
367
+ css('_bg[#1a1d24]') // background:#1a1d24
368
+ css('_shadow[0_4px_6px_rgba(0,0,0,0.1)]') // box-shadow (underscores → spaces)
369
+ css('_p[clamp(1rem,2vw,2rem)]') // padding with clamp()
370
+ css('_sm:w[512px]') // responsive arbitrary value
371
+ ```
372
+
373
+ Syntax: `_prop[value]`. Underscores in value are converted to spaces.
374
+
375
+ | Prefix | Property | Prefix | Property |
376
+ |--------|----------|--------|----------|
377
+ | `w` | width | `h` | height |
378
+ | `mw` | max-width | `mh` | max-height |
379
+ | `minw` | min-width | `minh` | min-height |
380
+ | `p/pt/pr/pb/pl` | padding | `px/py` | padding-inline/block |
381
+ | `m/mt/mr/mb/ml` | margin | `mx/my` | margin-inline/block |
382
+ | `gap/gx/gy` | gap | `t` | font-size |
383
+ | `lh` | line-height | `fw` | font-weight |
384
+ | `ls` | letter-spacing | `r` | border-radius |
385
+ | `bg` | background | `fg` | color |
386
+ | `bc` | border-color | `z` | z-index |
387
+ | `op` | opacity | `shadow` | box-shadow |
388
+ | `top/right/bottom/left` | position | `inset` | inset |
389
+ | `bf` | backdrop-filter | | |
390
+
391
+ ## Backdrop Filter Atoms (Composable)
392
+
393
+ Composable backdrop-filter via CSS variable composition. Combine blur + saturate + brightness.
394
+
395
+ ```js
396
+ css('_bfblur12 _bfsat150') // blur(12px) + saturate(1.5)
397
+ css('_bfblur8 _bfsat180 _bfbright110') // blur + saturate + brightness
398
+ css('_lg:bfblur16') // responsive backdrop blur
399
+ ```
400
+
401
+ **Blur:** `_bfblur0`, `_bfblur4`, `_bfblur8`, `_bfblur12`, `_bfblur16`, `_bfblur20`, `_bfblur24`
402
+
403
+ **Saturate:** `_bfsat100`, `_bfsat125`, `_bfsat150`, `_bfsat180`, `_bfsat200`
404
+
405
+ **Brightness:** `_bfbright90`, `_bfbright100`, `_bfbright110`, `_bfbright120`
406
+
407
+ **Regular filter atoms:** `_fblur4`, `_fblur8`, `_fblur16`, `_fgray`, `_fgray50`, `_finvert`, `_fbright50`, `_fbright75`, `_fbright110`
408
+
409
+ ## Custom Atoms via `define()`
410
+
411
+ When neither standard atoms nor `ARB_PROPS` bracket notation cover a CSS property, use `define()` to create a reusable atom instead of falling back to inline `style:`.
412
+
413
+ ```js
414
+ import { define, css } from 'decantr/css';
415
+
416
+ define('_selectNone', 'user-select:none');
417
+ define('_peNone', 'pointer-events:none');
418
+ define('_rotated45', 'transform:rotate(45deg)');
419
+ define('_curNotAllowed', 'cursor:not-allowed');
420
+
421
+ // Use like any atom:
422
+ div({ class: css('_selectNone _peNone _rotated45') });
423
+ ```
424
+
425
+ **When to use `define()`:**
426
+ - The CSS property has no `ARB_PROPS` prefix (e.g., `transform`, `user-select`, `pointer-events`, `clip-path`)
427
+ - You need the same static value in multiple places
428
+ - You want to avoid inline `style:` for a value known at author time
429
+
430
+ **When NOT to use `define()`:**
431
+ - The value is computed at runtime (use `style:` with signals/DOM measurements)
432
+ - A standard atom or bracket notation already covers it (check this file first)
433
+
434
+ **Escalation path:** (1) Standard atom → (2) Bracket notation `_w[32px]` → (3) `define()` → (4) Propose adding to `src/css/atoms.js` if broadly useful. Inline `style:` for static values is ALWAYS a bug.
435
+
436
+ ---
437
+
438
+ ## Pseudo-Class Prefixes
439
+
440
+ Compose ANY atom with interactive state pseudo-classes:
441
+
442
+ | Prefix | Pseudo-class | Example |
443
+ |--------|-------------|---------|
444
+ | `_h:` | `:hover` | `_h:bgprimary` — primary bg on hover |
445
+ | `_f:` | `:focus` | `_f:bcprimary` — primary border on focus |
446
+ | `_fv:` | `:focus-visible` | `_fv:ring2` — ring on keyboard focus |
447
+ | `_a:` | `:active` | `_a:bgmuted` — muted bg on press |
448
+ | `_fw:` | `:focus-within` | `_fw:bcprimary` — border when child focused |
449
+
450
+ **Combinations:**
451
+ - Responsive + pseudo: `_sm:h:bgmuted` — hover bg at sm+ breakpoint
452
+ - Pseudo + opacity: `_h:bgprimary/50` — 50% opacity primary bg on hover
453
+ - Pseudo + arbitrary: `_h:bg[rgba(255,255,255,0.1)]` — arbitrary bg on hover
454
+
455
+ ## Ring Utilities
456
+
457
+ Focus indicators and decorative outlines using `--d-ring` token:
458
+
459
+ | Atom | Output |
460
+ |------|--------|
461
+ | `_ring1` | `box-shadow: 0 0 0 1px var(--d-ring)` |
462
+ | `_ring2` | `box-shadow: 0 0 0 2px var(--d-ring)` |
463
+ | `_ring4` | `box-shadow: 0 0 0 4px var(--d-ring)` |
464
+ | `_ring0` | `box-shadow: none` (remove ring) |
465
+ | `_ringPrimary` | `--d-ring: var(--d-primary)` |
466
+ | `_ringAccent` | `--d-ring: var(--d-accent)` |
467
+ | `_ringBorder` | `--d-ring: var(--d-border)` |
468
+
469
+ Common pattern: `css('_fv:ring2 _ringPrimary')` — 2px primary ring on keyboard focus.
470
+
471
+ ## Transition Shortcuts
472
+
473
+ | Atom | Properties |
474
+ |------|-----------|
475
+ | `_transColors` | color, background-color, border-color, fill, stroke (0.2s ease) |
476
+ | `_transOpacity` | opacity (0.2s ease) |
477
+ | `_transTransform` | transform (0.2s ease) |
478
+ | `_transShadow` | box-shadow (0.2s ease) |
479
+ | `_trans[color_0.15s_ease]` | Arbitrary transition (underscores → spaces) |
480
+
481
+ ## Prose Typography
482
+
483
+ `_prose` adds the `d-prose` class, which applies typographic styles to nested HTML content (h1-h4, p, blockquote, code, pre, ul, ol, hr, a, img, table).
484
+
485
+ ```js
486
+ div({ class: css('_prose') },
487
+ h('h2', 'Title'),
488
+ h('p', 'Body text with ', h('code', 'inline code'), '.'),
489
+ h('blockquote', 'A highlighted quote.')
490
+ );
491
+ ```
492
+
493
+ ## Divide Utilities
494
+
495
+ | Atom | Output |
496
+ |------|--------|
497
+ | `_divideY` | Horizontal border between stacked children |
498
+ | `_divideX` | Vertical border between inline children |
499
+
500
+ Uses `var(--d-border)` for color. Applied via child selector `> :not(:first-child)`.
501
+
502
+ ## Text Wrapping
503
+
504
+ | Atom | Output |
505
+ |------|--------|
506
+ | `_textBalance` | `text-wrap: balance` — balanced line lengths |
507
+ | `_textPretty` | `text-wrap: pretty` — optimized line breaks |
508
+
509
+ ## Scroll Behavior
510
+
511
+ | Atom | Output |
512
+ |------|--------|
513
+ | `_scrollSmooth` | `scroll-behavior: smooth` |
514
+
515
+ ---
516
+
517
+ **See also:** `reference/spatial-guidelines.md`, `reference/tokens.md`, `reference/compound-spacing.md`