@tenphi/tasty 0.0.0-snapshot.01d8a9e

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 (332) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +635 -0
  3. package/dist/_virtual/_rolldown/runtime.js +7 -0
  4. package/dist/chunks/cacheKey.d.ts +1 -0
  5. package/dist/chunks/cacheKey.js +77 -0
  6. package/dist/chunks/cacheKey.js.map +1 -0
  7. package/dist/chunks/definitions.d.ts +37 -0
  8. package/dist/chunks/definitions.js +258 -0
  9. package/dist/chunks/definitions.js.map +1 -0
  10. package/dist/chunks/index.d.ts +1 -0
  11. package/dist/chunks/renderChunk.d.ts +1 -0
  12. package/dist/chunks/renderChunk.js +59 -0
  13. package/dist/chunks/renderChunk.js.map +1 -0
  14. package/dist/compute-styles.d.ts +31 -0
  15. package/dist/compute-styles.js +336 -0
  16. package/dist/compute-styles.js.map +1 -0
  17. package/dist/config.d.ts +407 -0
  18. package/dist/config.js +591 -0
  19. package/dist/config.js.map +1 -0
  20. package/dist/core/index.d.ts +34 -0
  21. package/dist/core/index.js +27 -0
  22. package/dist/counter-style/index.js +51 -0
  23. package/dist/counter-style/index.js.map +1 -0
  24. package/dist/debug.d.ts +89 -0
  25. package/dist/debug.js +453 -0
  26. package/dist/debug.js.map +1 -0
  27. package/dist/font-face/index.js +63 -0
  28. package/dist/font-face/index.js.map +1 -0
  29. package/dist/hooks/index.d.ts +7 -0
  30. package/dist/hooks/useCounterStyle.d.ts +36 -0
  31. package/dist/hooks/useCounterStyle.js +65 -0
  32. package/dist/hooks/useCounterStyle.js.map +1 -0
  33. package/dist/hooks/useFontFace.d.ts +45 -0
  34. package/dist/hooks/useFontFace.js +66 -0
  35. package/dist/hooks/useFontFace.js.map +1 -0
  36. package/dist/hooks/useGlobalStyles.d.ts +46 -0
  37. package/dist/hooks/useGlobalStyles.js +88 -0
  38. package/dist/hooks/useGlobalStyles.js.map +1 -0
  39. package/dist/hooks/useKeyframes.d.ts +58 -0
  40. package/dist/hooks/useKeyframes.js +55 -0
  41. package/dist/hooks/useKeyframes.js.map +1 -0
  42. package/dist/hooks/useProperty.d.ts +81 -0
  43. package/dist/hooks/useProperty.js +96 -0
  44. package/dist/hooks/useProperty.js.map +1 -0
  45. package/dist/hooks/useRawCSS.d.ts +22 -0
  46. package/dist/hooks/useRawCSS.js +103 -0
  47. package/dist/hooks/useRawCSS.js.map +1 -0
  48. package/dist/hooks/useStyles.d.ts +40 -0
  49. package/dist/hooks/useStyles.js +31 -0
  50. package/dist/hooks/useStyles.js.map +1 -0
  51. package/dist/index.d.ts +51 -0
  52. package/dist/index.js +36 -0
  53. package/dist/injector/index.d.ts +182 -0
  54. package/dist/injector/index.js +185 -0
  55. package/dist/injector/index.js.map +1 -0
  56. package/dist/injector/injector.d.ts +198 -0
  57. package/dist/injector/injector.js +651 -0
  58. package/dist/injector/injector.js.map +1 -0
  59. package/dist/injector/sheet-manager.d.ts +132 -0
  60. package/dist/injector/sheet-manager.js +699 -0
  61. package/dist/injector/sheet-manager.js.map +1 -0
  62. package/dist/injector/types.d.ts +235 -0
  63. package/dist/keyframes/index.js +206 -0
  64. package/dist/keyframes/index.js.map +1 -0
  65. package/dist/parser/classify.js +319 -0
  66. package/dist/parser/classify.js.map +1 -0
  67. package/dist/parser/const.js +60 -0
  68. package/dist/parser/const.js.map +1 -0
  69. package/dist/parser/lru.js +109 -0
  70. package/dist/parser/lru.js.map +1 -0
  71. package/dist/parser/parser.d.ts +25 -0
  72. package/dist/parser/parser.js +115 -0
  73. package/dist/parser/parser.js.map +1 -0
  74. package/dist/parser/tokenizer.js +69 -0
  75. package/dist/parser/tokenizer.js.map +1 -0
  76. package/dist/parser/types.d.ts +51 -0
  77. package/dist/parser/types.js +46 -0
  78. package/dist/parser/types.js.map +1 -0
  79. package/dist/pipeline/conditions.d.ts +134 -0
  80. package/dist/pipeline/conditions.js +406 -0
  81. package/dist/pipeline/conditions.js.map +1 -0
  82. package/dist/pipeline/exclusive.js +283 -0
  83. package/dist/pipeline/exclusive.js.map +1 -0
  84. package/dist/pipeline/index.d.ts +55 -0
  85. package/dist/pipeline/index.js +708 -0
  86. package/dist/pipeline/index.js.map +1 -0
  87. package/dist/pipeline/materialize.js +1157 -0
  88. package/dist/pipeline/materialize.js.map +1 -0
  89. package/dist/pipeline/parseStateKey.d.ts +15 -0
  90. package/dist/pipeline/parseStateKey.js +446 -0
  91. package/dist/pipeline/parseStateKey.js.map +1 -0
  92. package/dist/pipeline/simplify.js +690 -0
  93. package/dist/pipeline/simplify.js.map +1 -0
  94. package/dist/pipeline/warnings.js +18 -0
  95. package/dist/pipeline/warnings.js.map +1 -0
  96. package/dist/plugins/index.d.ts +2 -0
  97. package/dist/plugins/okhsl-plugin.d.ts +35 -0
  98. package/dist/plugins/okhsl-plugin.js +97 -0
  99. package/dist/plugins/okhsl-plugin.js.map +1 -0
  100. package/dist/plugins/types.d.ts +87 -0
  101. package/dist/properties/index.js +222 -0
  102. package/dist/properties/index.js.map +1 -0
  103. package/dist/properties/property-type-resolver.d.ts +24 -0
  104. package/dist/properties/property-type-resolver.js +90 -0
  105. package/dist/properties/property-type-resolver.js.map +1 -0
  106. package/dist/rsc-cache.js +79 -0
  107. package/dist/rsc-cache.js.map +1 -0
  108. package/dist/ssr/astro-client.d.ts +1 -0
  109. package/dist/ssr/astro-client.js +19 -0
  110. package/dist/ssr/astro-client.js.map +1 -0
  111. package/dist/ssr/astro-middleware.d.ts +15 -0
  112. package/dist/ssr/astro-middleware.js +19 -0
  113. package/dist/ssr/astro-middleware.js.map +1 -0
  114. package/dist/ssr/astro.d.ts +108 -0
  115. package/dist/ssr/astro.js +149 -0
  116. package/dist/ssr/astro.js.map +1 -0
  117. package/dist/ssr/async-storage.d.ts +17 -0
  118. package/dist/ssr/async-storage.js +44 -0
  119. package/dist/ssr/async-storage.js.map +1 -0
  120. package/dist/ssr/collect-auto-properties.js +58 -0
  121. package/dist/ssr/collect-auto-properties.js.map +1 -0
  122. package/dist/ssr/collector.d.ts +94 -0
  123. package/dist/ssr/collector.js +233 -0
  124. package/dist/ssr/collector.js.map +1 -0
  125. package/dist/ssr/context.js +16 -0
  126. package/dist/ssr/context.js.map +1 -0
  127. package/dist/ssr/format-global-rules.js +22 -0
  128. package/dist/ssr/format-global-rules.js.map +1 -0
  129. package/dist/ssr/format-keyframes.js +69 -0
  130. package/dist/ssr/format-keyframes.js.map +1 -0
  131. package/dist/ssr/format-property.js +49 -0
  132. package/dist/ssr/format-property.js.map +1 -0
  133. package/dist/ssr/format-rules.js +73 -0
  134. package/dist/ssr/format-rules.js.map +1 -0
  135. package/dist/ssr/hydrate.d.ts +29 -0
  136. package/dist/ssr/hydrate.js +45 -0
  137. package/dist/ssr/hydrate.js.map +1 -0
  138. package/dist/ssr/index.d.ts +4 -0
  139. package/dist/ssr/index.js +10 -0
  140. package/dist/ssr/index.js.map +1 -0
  141. package/dist/ssr/next.d.ts +46 -0
  142. package/dist/ssr/next.js +75 -0
  143. package/dist/ssr/next.js.map +1 -0
  144. package/dist/ssr/ssr-collector-ref.js +29 -0
  145. package/dist/ssr/ssr-collector-ref.js.map +1 -0
  146. package/dist/states/index.d.ts +49 -0
  147. package/dist/states/index.js +170 -0
  148. package/dist/states/index.js.map +1 -0
  149. package/dist/static/index.d.ts +5 -0
  150. package/dist/static/index.js +4 -0
  151. package/dist/static/inject.d.ts +5 -0
  152. package/dist/static/inject.js +17 -0
  153. package/dist/static/inject.js.map +1 -0
  154. package/dist/static/tastyStatic.d.ts +46 -0
  155. package/dist/static/tastyStatic.js +30 -0
  156. package/dist/static/tastyStatic.js.map +1 -0
  157. package/dist/static/types.d.ts +49 -0
  158. package/dist/static/types.js +24 -0
  159. package/dist/static/types.js.map +1 -0
  160. package/dist/styles/border.d.ts +25 -0
  161. package/dist/styles/border.js +120 -0
  162. package/dist/styles/border.js.map +1 -0
  163. package/dist/styles/color.d.ts +14 -0
  164. package/dist/styles/color.js +26 -0
  165. package/dist/styles/color.js.map +1 -0
  166. package/dist/styles/const.js +17 -0
  167. package/dist/styles/const.js.map +1 -0
  168. package/dist/styles/createStyle.js +79 -0
  169. package/dist/styles/createStyle.js.map +1 -0
  170. package/dist/styles/dimension.js +109 -0
  171. package/dist/styles/dimension.js.map +1 -0
  172. package/dist/styles/directional.js +133 -0
  173. package/dist/styles/directional.js.map +1 -0
  174. package/dist/styles/display.d.ts +30 -0
  175. package/dist/styles/display.js +73 -0
  176. package/dist/styles/display.js.map +1 -0
  177. package/dist/styles/fade.d.ts +15 -0
  178. package/dist/styles/fade.js +62 -0
  179. package/dist/styles/fade.js.map +1 -0
  180. package/dist/styles/fill.d.ts +42 -0
  181. package/dist/styles/fill.js +51 -0
  182. package/dist/styles/fill.js.map +1 -0
  183. package/dist/styles/flow.d.ts +16 -0
  184. package/dist/styles/flow.js +12 -0
  185. package/dist/styles/flow.js.map +1 -0
  186. package/dist/styles/gap.d.ts +31 -0
  187. package/dist/styles/gap.js +38 -0
  188. package/dist/styles/gap.js.map +1 -0
  189. package/dist/styles/height.d.ts +17 -0
  190. package/dist/styles/height.js +19 -0
  191. package/dist/styles/height.js.map +1 -0
  192. package/dist/styles/index.d.ts +1 -0
  193. package/dist/styles/index.js +8 -0
  194. package/dist/styles/index.js.map +1 -0
  195. package/dist/styles/inset.d.ts +24 -0
  196. package/dist/styles/inset.js +34 -0
  197. package/dist/styles/inset.js.map +1 -0
  198. package/dist/styles/list.d.ts +16 -0
  199. package/dist/styles/list.js +100 -0
  200. package/dist/styles/list.js.map +1 -0
  201. package/dist/styles/margin.d.ts +24 -0
  202. package/dist/styles/margin.js +32 -0
  203. package/dist/styles/margin.js.map +1 -0
  204. package/dist/styles/outline.d.ts +29 -0
  205. package/dist/styles/outline.js +55 -0
  206. package/dist/styles/outline.js.map +1 -0
  207. package/dist/styles/padding.d.ts +24 -0
  208. package/dist/styles/padding.js +32 -0
  209. package/dist/styles/padding.js.map +1 -0
  210. package/dist/styles/placement.d.ts +37 -0
  211. package/dist/styles/placement.js +74 -0
  212. package/dist/styles/placement.js.map +1 -0
  213. package/dist/styles/predefined.d.ts +71 -0
  214. package/dist/styles/predefined.js +237 -0
  215. package/dist/styles/predefined.js.map +1 -0
  216. package/dist/styles/preset.d.ts +52 -0
  217. package/dist/styles/preset.js +127 -0
  218. package/dist/styles/preset.js.map +1 -0
  219. package/dist/styles/radius.d.ts +12 -0
  220. package/dist/styles/radius.js +83 -0
  221. package/dist/styles/radius.js.map +1 -0
  222. package/dist/styles/scrollMargin.d.ts +24 -0
  223. package/dist/styles/scrollMargin.js +32 -0
  224. package/dist/styles/scrollMargin.js.map +1 -0
  225. package/dist/styles/scrollbar.d.ts +25 -0
  226. package/dist/styles/scrollbar.js +51 -0
  227. package/dist/styles/scrollbar.js.map +1 -0
  228. package/dist/styles/shadow.d.ts +14 -0
  229. package/dist/styles/shadow.js +25 -0
  230. package/dist/styles/shadow.js.map +1 -0
  231. package/dist/styles/shared.js +17 -0
  232. package/dist/styles/shared.js.map +1 -0
  233. package/dist/styles/transition.d.ts +14 -0
  234. package/dist/styles/transition.js +159 -0
  235. package/dist/styles/transition.js.map +1 -0
  236. package/dist/styles/types.d.ts +564 -0
  237. package/dist/styles/width.d.ts +17 -0
  238. package/dist/styles/width.js +19 -0
  239. package/dist/styles/width.js.map +1 -0
  240. package/dist/tasty.d.ts +134 -0
  241. package/dist/tasty.js +248 -0
  242. package/dist/tasty.js.map +1 -0
  243. package/dist/types.d.ts +184 -0
  244. package/dist/utils/cache-wrapper.js +21 -0
  245. package/dist/utils/cache-wrapper.js.map +1 -0
  246. package/dist/utils/case-converter.js +8 -0
  247. package/dist/utils/case-converter.js.map +1 -0
  248. package/dist/utils/color-math.d.ts +46 -0
  249. package/dist/utils/color-math.js +749 -0
  250. package/dist/utils/color-math.js.map +1 -0
  251. package/dist/utils/color-space.d.ts +5 -0
  252. package/dist/utils/color-space.js +228 -0
  253. package/dist/utils/color-space.js.map +1 -0
  254. package/dist/utils/colors.d.ts +5 -0
  255. package/dist/utils/colors.js +10 -0
  256. package/dist/utils/colors.js.map +1 -0
  257. package/dist/utils/css-types.d.ts +7 -0
  258. package/dist/utils/deps-equal.js +15 -0
  259. package/dist/utils/deps-equal.js.map +1 -0
  260. package/dist/utils/dotize.d.ts +26 -0
  261. package/dist/utils/dotize.js +122 -0
  262. package/dist/utils/dotize.js.map +1 -0
  263. package/dist/utils/filter-base-props.d.ts +15 -0
  264. package/dist/utils/filter-base-props.js +45 -0
  265. package/dist/utils/filter-base-props.js.map +1 -0
  266. package/dist/utils/get-display-name.d.ts +7 -0
  267. package/dist/utils/get-display-name.js +10 -0
  268. package/dist/utils/get-display-name.js.map +1 -0
  269. package/dist/utils/has-keys.js +13 -0
  270. package/dist/utils/has-keys.js.map +1 -0
  271. package/dist/utils/hash.js +14 -0
  272. package/dist/utils/hash.js.map +1 -0
  273. package/dist/utils/is-dev-env.js +19 -0
  274. package/dist/utils/is-dev-env.js.map +1 -0
  275. package/dist/utils/is-valid-element-type.js +15 -0
  276. package/dist/utils/is-valid-element-type.js.map +1 -0
  277. package/dist/utils/merge-styles.d.ts +7 -0
  278. package/dist/utils/merge-styles.js +145 -0
  279. package/dist/utils/merge-styles.js.map +1 -0
  280. package/dist/utils/mod-attrs.d.ts +6 -0
  281. package/dist/utils/mod-attrs.js +20 -0
  282. package/dist/utils/mod-attrs.js.map +1 -0
  283. package/dist/utils/process-tokens.d.ts +17 -0
  284. package/dist/utils/process-tokens.js +83 -0
  285. package/dist/utils/process-tokens.js.map +1 -0
  286. package/dist/utils/resolve-recipes.d.ts +17 -0
  287. package/dist/utils/resolve-recipes.js +146 -0
  288. package/dist/utils/resolve-recipes.js.map +1 -0
  289. package/dist/utils/selector-transform.js +32 -0
  290. package/dist/utils/selector-transform.js.map +1 -0
  291. package/dist/utils/string.js +8 -0
  292. package/dist/utils/string.js.map +1 -0
  293. package/dist/utils/styles.d.ts +99 -0
  294. package/dist/utils/styles.js +220 -0
  295. package/dist/utils/styles.js.map +1 -0
  296. package/dist/utils/typography.d.ts +58 -0
  297. package/dist/utils/typography.js +51 -0
  298. package/dist/utils/typography.js.map +1 -0
  299. package/dist/utils/warnings.d.ts +16 -0
  300. package/dist/utils/warnings.js +16 -0
  301. package/dist/utils/warnings.js.map +1 -0
  302. package/dist/zero/babel.d.ts +81 -0
  303. package/dist/zero/babel.js +462 -0
  304. package/dist/zero/babel.js.map +1 -0
  305. package/dist/zero/css-writer.d.ts +45 -0
  306. package/dist/zero/css-writer.js +73 -0
  307. package/dist/zero/css-writer.js.map +1 -0
  308. package/dist/zero/extractor.d.ts +24 -0
  309. package/dist/zero/extractor.js +266 -0
  310. package/dist/zero/extractor.js.map +1 -0
  311. package/dist/zero/index.d.ts +3 -0
  312. package/dist/zero/index.js +3 -0
  313. package/dist/zero/next.d.ts +86 -0
  314. package/dist/zero/next.js +143 -0
  315. package/dist/zero/next.js.map +1 -0
  316. package/docs/PIPELINE.md +519 -0
  317. package/docs/README.md +31 -0
  318. package/docs/adoption.md +298 -0
  319. package/docs/comparison.md +419 -0
  320. package/docs/configuration.md +394 -0
  321. package/docs/debug.md +318 -0
  322. package/docs/design-system.md +436 -0
  323. package/docs/dsl.md +688 -0
  324. package/docs/getting-started.md +217 -0
  325. package/docs/injector.md +544 -0
  326. package/docs/methodology.md +616 -0
  327. package/docs/react-api.md +557 -0
  328. package/docs/ssr.md +442 -0
  329. package/docs/styles.md +596 -0
  330. package/docs/tasty-static.md +532 -0
  331. package/package.json +221 -0
  332. package/tasty.config.ts +14 -0
@@ -0,0 +1,298 @@
1
+ # Adoption Guide
2
+
3
+ Tasty is not a drop-in replacement for another styling library. It is a **substrate for building a design-system-defined styling language**: what the comparison guide calls a house styling language. That means adoption usually starts where styling for reusable, stateful components has already become a composition problem, not with an all-at-once rewrite.
4
+
5
+ This guide is for design-system maintainers and platform engineers evaluating Tasty or introducing it into an existing codebase. Use this document for rollout strategy and adoption sequencing; use the [Comparison guide](comparison.md) when the open question is whether Tasty is the right tool in the first place.
6
+
7
+ ---
8
+
9
+ ## Where Tasty sits in the stack
10
+
11
+ Tasty is not the surface your product engineers interact with directly. It sits one layer below:
12
+
13
+ ```
14
+ Product code
15
+ └─ DS components (Button, Card, Layout, ...)
16
+ └─ Tasty engine (tasty(), configure(), style functions)
17
+ └─ CSS (mutually exclusive selectors, tokens, custom properties)
18
+ ```
19
+
20
+ **What Tasty owns:**
21
+ - The DSL and value parser (tokens, custom units, auto-calc, color opacity)
22
+ - State compilation (mutually exclusive selectors from state maps)
23
+ - Style injection and deduplication (runtime or build-time)
24
+ - The `tasty()` component factory and hooks API
25
+
26
+ **What the DS team owns:**
27
+ - Token names and values (colors, spacing, typography)
28
+ - Custom units and their semantics
29
+ - State aliases (`@mobile`, `@dark`, `@compact`)
30
+ - Recipes (reusable style bundles)
31
+ - Which style props each component exposes
32
+ - Sub-element structure for compound components
33
+ - The override and extension rules product teams follow
34
+
35
+ Two teams using Tasty can end up with very different authoring models. That is by design.
36
+
37
+ ---
38
+
39
+ ## Who should adopt Tasty
40
+
41
+ **Strong fit:**
42
+ - A design-system or platform team that wants to define a governed styling language
43
+ - Components with complex, intersecting states (hover + disabled + theme + breakpoint)
44
+ - Teams that need deterministic style resolution without cascade/specificity bugs
45
+ - Organizations where styling decisions should be centralized, not distributed
46
+
47
+ **Not the right fit:**
48
+ - Solo developers building a one-off app with minimal UI structure
49
+ - Teams that want a shared utility vocabulary and direct markup authoring (Tailwind is better here)
50
+ - Projects where low ceremony matters more than central governance
51
+ - Codebases where intersecting state complexity is low
52
+
53
+ For a detailed comparison with Tailwind, Panda CSS, vanilla-extract, StyleX, Stitches, and Emotion, see the [Comparison guide](comparison.md).
54
+
55
+ ---
56
+
57
+ ## What you are expected to define
58
+
59
+ Tasty provides the engine. The DS team defines the language that runs on it. Here is what that typically involves:
60
+
61
+ | Layer | What you define | Where |
62
+ |-------|----------------|-------|
63
+ | **Tokens** | Color names, spacing scale, border widths, radii | `configure({ tokens })` |
64
+ | **Units** | Custom multiplier units (`x`, `r`, `bw`, or your own) | `configure({ units })` |
65
+ | **State aliases** | Responsive breakpoints, theme modes, feature flags | `configure({ states })` |
66
+ | **Recipes** | Reusable style bundles (card, elevated, input-reset) | `configure({ recipes })` |
67
+ | **Typography** | Preset definitions (h1-h6, t1-t4, etc.) | `configure({ presets: { ... } })` |
68
+ | **Style props** | Which CSS properties each component exposes as React props | `styleProps` in each component |
69
+ | **Sub-elements** | Inner parts of compound components (Title, Icon, Content) | `elements` + capitalized keys in `styles` |
70
+ | **Override rules** | How product engineers extend or constrain components | Styled wrappers via `tasty(Base, { ... })` |
71
+
72
+ The same engine can power a minimal design system with a handful of tokens:
73
+
74
+ ```tsx
75
+ configure({
76
+ tokens: { '#bg': '#white', '#text': '#111' },
77
+ states: { '@dark': '@root(schema=dark)' },
78
+ });
79
+ ```
80
+
81
+ ...or an enterprise-scale system with dozens of tokens, multiple state aliases, typography presets, recipes, and custom units. The scope is yours to decide.
82
+
83
+ Here is how the layers connect end-to-end. The DS team configures the engine, defines components, and product engineers consume them:
84
+
85
+ ```tsx
86
+ // ds/config.ts — DS team defines the language
87
+ configure({
88
+ tokens: { '#primary': 'oklch(55% 0.25 265)', '#surface': '#fff', '#text': '#111' },
89
+ states: { '@mobile': '@media(w < 768px)', '@dark': '@root(schema=dark)' },
90
+ recipes: { card: { padding: '4x', fill: '#surface', radius: '1r', border: true } },
91
+ });
92
+
93
+ // ds/components/Card.tsx — DS team builds components on top
94
+ const Card = tasty({
95
+ styles: {
96
+ recipe: 'card',
97
+ Title: { preset: 'h3', color: '#primary' },
98
+ Body: { preset: 't2', color: '#text' },
99
+ },
100
+ elements: { Title: 'h2', Body: 'div' },
101
+ styleProps: ['padding', 'fill'],
102
+ });
103
+
104
+ // app/Dashboard.tsx — product engineer uses the component
105
+ <Card padding={{ '': '4x', '@mobile': '2x' }}>
106
+ <Card.Title>Monthly Revenue</Card.Title>
107
+ <Card.Body>$1.2M — up 12% from last month</Card.Body>
108
+ </Card>
109
+ ```
110
+
111
+ See [Configuration](configuration.md) for the full `configure()` API.
112
+
113
+ ---
114
+
115
+ ## Incremental adoption
116
+
117
+ You do not need to adopt everything at once. Tasty is designed to be introduced layer by layer.
118
+
119
+ A practical way to start is with the components that already suffer from intersecting state and variant logic: buttons, inputs, menus, disclosures, dialogs, list items, interactive cards, and compound components. Those are the places where deterministic resolution pays off fastest.
120
+
121
+ ### Phase 1 -- Tokens and units
122
+
123
+ Start by defining your design tokens and custom units. This is the lowest-risk step: it only configures the parser and does not require rewriting any components.
124
+
125
+ ```tsx
126
+ import { configure } from '@tenphi/tasty';
127
+
128
+ configure({
129
+ tokens: {
130
+ '#primary': 'oklch(55% 0.25 265)',
131
+ '#surface': '#white',
132
+ '#text': '#111',
133
+ '$card-padding': '4x',
134
+ },
135
+ // Common units (x, r, bw, ow, cr) are built-in.
136
+ // A DS typically redefines them to use CSS custom properties
137
+ // so that the actual scale is controlled via CSS, not JS:
138
+ units: {
139
+ x: 'var(--gap)', // 2x → calc(var(--gap) * 2)
140
+ r: 'var(--radius)',
141
+ bw: 'var(--border-width)',
142
+ },
143
+ });
144
+ ```
145
+
146
+ ### Phase 2 -- State aliases and recipes
147
+
148
+ Define the state vocabulary your components will share. This is where you start encoding your team's conventions.
149
+
150
+ ```tsx
151
+ configure({
152
+ states: {
153
+ '@mobile': '@media(w < 768px)',
154
+ '@tablet': '@media(w < 1024px)',
155
+ '@dark': '@root(schema=dark) | (!@root(schema) & @media(prefers-color-scheme: dark))',
156
+ },
157
+ recipes: {
158
+ card: { padding: '4x', fill: '#surface', radius: '1r', border: true },
159
+ elevated: { shadow: '0 2x 4x #shadow' },
160
+ },
161
+ });
162
+ ```
163
+
164
+ ### Phase 3 -- Migrate a few primitives
165
+
166
+ Pick 2-3 widely used primitives (Box, Text, Button) and rewrite them with `tasty()`. Keep the public API identical so product code does not need to change.
167
+
168
+ ```tsx
169
+ const Box = tasty({
170
+ as: 'div',
171
+ styles: {
172
+ display: 'flex',
173
+ flow: 'column',
174
+ gap: '1x',
175
+ },
176
+ styleProps: ['gap', 'flow', 'padding', 'fill'],
177
+ });
178
+ ```
179
+
180
+ At this point you can validate the DSL, token workflow, and component authoring experience before expanding the rollout.
181
+
182
+ ### Phase 4 -- Encode complex states
183
+
184
+ Move the components with the most painful intersecting states (buttons with hover + disabled + theme variants, inputs with focus + error + readonly) to Tasty's state map syntax. This is where mutually exclusive selectors start paying off.
185
+
186
+ ```tsx
187
+ const Button = tasty({
188
+ as: 'button',
189
+ styles: {
190
+ fill: {
191
+ '': '#primary',
192
+ ':hover': '#primary-hover',
193
+ ':active': '#primary-pressed',
194
+ // `disabled` is a data-attribute modifier → [data-disabled].
195
+ // Tasty auto-applies it from the native `disabled` attribute.
196
+ // `[disabled]` (attribute selector) also works here.
197
+ disabled: '#surface',
198
+ },
199
+ color: {
200
+ '': '#on-primary',
201
+ disabled: '#text.40',
202
+ },
203
+ cursor: {
204
+ '': 'pointer',
205
+ disabled: 'not-allowed',
206
+ },
207
+ transition: 'theme',
208
+ },
209
+ });
210
+ ```
211
+
212
+ ### Phase 5 -- Standardize style props and sub-elements
213
+
214
+ Define which style props each component category exposes. Layout components get flow/gap/padding. Interactive components get positioning. Compound components declare sub-elements.
215
+
216
+ ```tsx
217
+ const Card = tasty({
218
+ styles: {
219
+ recipe: 'card elevated',
220
+ Title: { preset: 'h3', color: '#primary' },
221
+ Content: { color: '#text', preset: 't2' },
222
+ },
223
+ elements: { Title: 'h2', Content: 'div' },
224
+ styleProps: ['padding', 'fill', 'radius'],
225
+ });
226
+ ```
227
+
228
+ ### Phase 6 -- Expand to full DS coverage
229
+
230
+ Migrate the remaining components, add the [ESLint plugin](https://github.com/tenphi/eslint-plugin-tasty) to enforce style conventions at lint time, and consider [zero-runtime mode](tasty-static.md) for static or performance-critical pages.
231
+
232
+ ---
233
+
234
+ ## What changes for product engineers
235
+
236
+ When a DS is powered by Tasty, product engineers typically interact with **components, not Tasty itself**. Here is what changes from their perspective:
237
+
238
+ **They do not write CSS directly.** Styling decisions are embedded in the components the DS provides. Product code consumes components, tokens, and style props.
239
+
240
+ **Overrides use styled wrappers.** Instead of passing one-off `className` or `style` props, product engineers extend components:
241
+
242
+ ```tsx
243
+ import { tasty } from '@tenphi/tasty';
244
+ import { Button } from 'my-ds';
245
+
246
+ // Replace mode: providing '' (default) key replaces the parent's fill entirely
247
+ const DangerButton = tasty(Button, {
248
+ styles: {
249
+ fill: { '': '#danger', ':hover': '#danger-hover' },
250
+ },
251
+ });
252
+
253
+ // Extend mode: omitting '' key preserves parent states and adds/overrides
254
+ const LoadingButton = tasty(Button, {
255
+ styles: {
256
+ fill: {
257
+ loading: '#yellow', // new state appended
258
+ disabled: '#gray.20', // existing state overridden in place
259
+ },
260
+ },
261
+ });
262
+ ```
263
+
264
+ **Style props replace raw CSS.** Layout, spacing, and positioning are controlled through typed props on the components that expose them:
265
+
266
+ ```tsx
267
+ <Space flow="row" gap="2x" placeItems="center">
268
+ <Title>Dashboard</Title>
269
+ <Button placeSelf="end">Add Item</Button>
270
+ </Space>
271
+ ```
272
+
273
+ **Components are server components by default.** All `tasty()` components and style functions are hook-free, so they work as React Server Components without `'use client'`. In server-only contexts (Next.js RSC, Astro without `client:*` directives), they produce zero client JavaScript. Product engineers only add `'use client'` when their component needs actual React interactivity (state, effects, event handlers), never because of styling.
274
+
275
+ **No cascade/specificity concerns.** Tasty's mutually exclusive selectors mean extending a component cannot accidentally break another. Import order, class name collisions, and specificity arithmetic are non-issues.
276
+
277
+ ---
278
+
279
+ ## Migration and Interop Notes
280
+
281
+ - **From Tailwind**: keep utility-authored product surfaces as-is at first, and use Tasty to build or replace the design-system primitives underneath them instead of forcing an all-at-once markup rewrite.
282
+ - **From CSS-in-JS libraries**: start with shared primitives such as `Box`, `Text`, and `Button`, preserve the external component API, and move state logic into Tasty state maps so behavior changes without product-code churn.
283
+ - **From CSS Modules or plain CSS**: migrate token definitions and repeated patterns first, then wrap existing DOM structure with `tasty()` components gradually rather than converting every stylesheet at once.
284
+
285
+ ---
286
+
287
+ ## Learn more
288
+
289
+ - [README](../README.md) -- overview, quick start, and feature highlights
290
+ - [Getting Started](getting-started.md) -- installation, first component, tooling setup
291
+ - [Methodology](methodology.md) -- the recommended patterns for structuring Tasty components
292
+ - [Building a Design System](design-system.md) -- practical guide to building a DS layer with Tasty
293
+ - [Style DSL](dsl.md) -- state maps, tokens, units, extending semantics, keyframes, @property
294
+ - [React API](react-api.md) -- `tasty()` factory, component props, variants, sub-elements, style functions
295
+ - [Configuration](configuration.md) -- tokens, recipes, custom units, style handlers, and TypeScript extensions
296
+ - [Style Properties](styles.md) -- complete reference for all enhanced style properties
297
+ - [Comparison](comparison.md) -- positioning and trade-offs vs. other styling systems
298
+ - [Zero Runtime (tastyStatic)](tasty-static.md) -- build-time static styling with Babel plugin