@tenphi/tasty 0.10.1 → 0.12.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.
@@ -1,155 +1,8 @@
1
- # Usage Guide
1
+ # Style DSL Reference
2
2
 
3
- `tasty` is a powerful utility for creating styled React components with a declarative, design-system-integrated API. It combines the flexibility of CSS-in-JS with the consistency of a design system, enabling you to build maintainable, themeable components quickly.
3
+ This is the Tasty style language reference the value syntax, state mappings, tokens, units, extending semantics, and special declarations that apply to both runtime `tasty()` and build-time `tastyStatic()`.
4
4
 
5
- For global configuration (tokens, recipes, custom units, handlers), see **[Configuration](configuration.md)**.
6
-
7
- ---
8
-
9
- ## Quick Start
10
-
11
- ### Creating Your First Component
12
-
13
- ```jsx
14
- import { tasty } from '@tenphi/tasty';
15
-
16
- // Basic styled component
17
- const Card = tasty({
18
- as: 'div',
19
- styles: {
20
- padding: '4x',
21
- fill: '#white',
22
- border: true,
23
- radius: true,
24
- },
25
- styleProps: ['padding', 'fill'], // Expose styles as props
26
- });
27
-
28
- // Usage
29
- <Card>Hello World</Card>
30
- <Card padding="6x" fill="#gray.05">Custom Card</Card>
31
- ```
32
-
33
- ### Extending Existing Components
34
-
35
- > **Best Practice:** Always prefer creating styled wrappers over using the `styles` prop directly.
36
-
37
- ```jsx
38
- // Recommended
39
- const PrimaryButton = tasty(Button, {
40
- styles: {
41
- fill: '#purple',
42
- color: '#white',
43
- padding: '2x 4x',
44
- },
45
- });
46
-
47
- // Avoid
48
- <Button styles={{ fill: '#purple' }}>Click me</Button>
49
- ```
50
-
51
- #### Extending vs. Replacing State Maps
52
-
53
- When a style property uses a state map, the merge behavior depends on whether the child provides a `''` (default) key:
54
-
55
- - **No `''` key** — extend mode: parent states are preserved, child adds/overrides
56
- - **Has `''` key** — replace mode: child defines everything from scratch
57
-
58
- ```jsx
59
- // Parent has: fill: { '': '#white', hovered: '#blue', disabled: '#gray' }
60
-
61
- // Extend — no '' key, parent states preserved
62
- const MyButton = tasty(Button, {
63
- styles: {
64
- fill: {
65
- 'loading': '#yellow', // append new state
66
- 'disabled': '#gray.20', // override existing state in place
67
- },
68
- },
69
- });
70
-
71
- // Replace — has '' key, parent states dropped
72
- const MyButton = tasty(Button, {
73
- styles: {
74
- fill: {
75
- '': '#red',
76
- 'hovered': '#blue',
77
- },
78
- },
79
- });
80
- ```
81
-
82
- Use `'@inherit'` to pull a parent state value. In extend mode it repositions the state; in replace mode it cherry-picks it:
83
-
84
- ```jsx
85
- // Extend mode: reposition disabled to end (highest CSS priority)
86
- fill: {
87
- 'loading': '#yellow',
88
- disabled: '@inherit',
89
- }
90
-
91
- // Replace mode: cherry-pick disabled from parent
92
- fill: {
93
- '': '#red',
94
- disabled: '@inherit',
95
- }
96
- ```
97
-
98
- Use `null` inside a state map to remove a state, or `false` to block it entirely (tombstone):
99
-
100
- ```jsx
101
- fill: { pressed: null } // removes pressed from the result
102
- fill: { disabled: false } // tombstone — no CSS for disabled, blocks recipe too
103
- ```
104
-
105
- #### Resetting Properties with `null` and `false`
106
-
107
- ```jsx
108
- const SimpleButton = tasty(Button, {
109
- styles: {
110
- fill: null, // discard parent's fill, let recipe fill in
111
- border: false, // no border at all (tombstone — blocks recipe too)
112
- },
113
- });
114
- ```
115
-
116
- | Value | Meaning | Recipe fills in? |
117
- |-------|---------|-----------------|
118
- | `undefined` | Not provided — parent preserved | N/A |
119
- | `null` | Intentional unset — parent discarded | Yes |
120
- | `false` | Tombstone — blocks everything | No |
121
-
122
- ### Essential Patterns
123
-
124
- ```jsx
125
- // State-based styling
126
- const InteractiveCard = tasty({
127
- styles: {
128
- fill: {
129
- '': '#white',
130
- 'hovered': '#gray.05',
131
- 'pressed': '#gray.10',
132
- },
133
- },
134
- });
135
-
136
- // Using design tokens
137
- const TokenCard = tasty({
138
- styles: {
139
- fill: '#surface', // Color token
140
- color: '#text', // Color token
141
- padding: '2x', // Custom unit (gap × 2)
142
- radius: '1r', // Custom unit (border-radius)
143
- border: '1bw solid #border', // Border width token
144
- },
145
- });
146
- ```
147
-
148
- ---
149
-
150
- ## Configuration
151
-
152
- For tokens, recipes, custom units, style handlers, and other global settings, see **[Configuration](configuration.md)**.
5
+ For the runtime React API (`tasty()`, hooks, component props), see [Runtime API](runtime.md). For all enhanced style properties, see [Style Properties](styles.md). For global configuration, see [Configuration](configuration.md).
153
6
 
154
7
  ---
155
8
 
@@ -202,43 +55,7 @@ mods={{ hovered: true, theme: 'danger' }}
202
55
 
203
56
  ---
204
57
 
205
- ## Core Concepts
206
-
207
- ### Component Creation
208
-
209
- ```jsx
210
- // Create new element
211
- const Box = tasty({
212
- as: 'div',
213
- styles: { /* styles */ },
214
- });
215
-
216
- // Extend existing component
217
- const StyledButton = tasty(Button, {
218
- styles: { /* additional styles */ },
219
- });
220
- ```
221
-
222
- ### Style Props
223
-
224
- Use `styleProps` to expose style properties as direct component props:
225
-
226
- ```jsx
227
- const FlexibleBox = tasty({
228
- as: 'div',
229
- styles: {
230
- display: 'flex',
231
- padding: '2x',
232
- },
233
- styleProps: ['gap', 'align', 'placeContent', 'fill'],
234
- });
235
-
236
- <FlexibleBox gap="2x" align="center" fill="#surface">
237
- Content
238
- </FlexibleBox>
239
- ```
240
-
241
- ### Color Tokens & Opacity
58
+ ## Color Tokens & Opacity
242
59
 
243
60
  ```jsx
244
61
  color: '#purple', // Full opacity
@@ -249,7 +66,9 @@ fill: '#current.5', // → color-mix(in oklab, currentcolor 50%, transpa
249
66
  color: '(#primary, #secondary)', // Fallback syntax
250
67
  ```
251
68
 
252
- ### Built-in Units
69
+ ---
70
+
71
+ ## Built-in Units
253
72
 
254
73
  | Unit | Description | Example | CSS Output |
255
74
  |------|-------------|---------|------------|
@@ -264,9 +83,11 @@ color: '(#primary, #secondary)', // Fallback syntax
264
83
 
265
84
  You can register additional custom units via [`configure()`](configuration.md#options).
266
85
 
267
- ### Predefined Tokens
86
+ ---
87
+
88
+ ## Replace Tokens
268
89
 
269
- Tokens defined via [`configure({ tokens })`](configuration.md#predefined-tokens) are replaced at parse time and baked into the generated CSS:
90
+ Tokens defined via [`configure({ replaceTokens })`](configuration.md#replace-tokens-parse-time-substitution) are replaced at parse time and baked into the generated CSS:
270
91
 
271
92
  ```jsx
272
93
  const Card = tasty({
@@ -278,7 +99,9 @@ const Card = tasty({
278
99
  });
279
100
  ```
280
101
 
281
- ### Recipes
102
+ ---
103
+
104
+ ## Recipes
282
105
 
283
106
  Apply predefined style bundles (defined via [`configure({ recipes })`](configuration.md#recipes)) using the `recipe` style property:
284
107
 
@@ -323,7 +146,82 @@ const Custom = tasty({
323
146
  });
324
147
  ```
325
148
 
326
- ### Advanced States (`@` prefix)
149
+ ---
150
+
151
+ ## Extending vs. Replacing State Maps
152
+
153
+ When a style property uses a state map, the merge behavior depends on whether the child provides a `''` (default) key:
154
+
155
+ - **No `''` key** — extend mode: parent states are preserved, child adds/overrides
156
+ - **Has `''` key** — replace mode: child defines everything from scratch
157
+
158
+ ```jsx
159
+ // Parent has: fill: { '': '#white', hovered: '#blue', disabled: '#gray' }
160
+
161
+ // Extend — no '' key, parent states preserved
162
+ const MyButton = tasty(Button, {
163
+ styles: {
164
+ fill: {
165
+ 'loading': '#yellow', // append new state
166
+ 'disabled': '#gray.20', // override existing state in place
167
+ },
168
+ },
169
+ });
170
+
171
+ // Replace — has '' key, parent states dropped
172
+ const MyButton = tasty(Button, {
173
+ styles: {
174
+ fill: {
175
+ '': '#red',
176
+ 'hovered': '#blue',
177
+ },
178
+ },
179
+ });
180
+ ```
181
+
182
+ Use `'@inherit'` to pull a parent state value. In extend mode it repositions the state; in replace mode it cherry-picks it:
183
+
184
+ ```jsx
185
+ // Extend mode: reposition disabled to end (highest CSS priority)
186
+ fill: {
187
+ 'loading': '#yellow',
188
+ disabled: '@inherit',
189
+ }
190
+
191
+ // Replace mode: cherry-pick disabled from parent
192
+ fill: {
193
+ '': '#red',
194
+ disabled: '@inherit',
195
+ }
196
+ ```
197
+
198
+ Use `null` inside a state map to remove a state, or `false` to block it entirely (tombstone):
199
+
200
+ ```jsx
201
+ fill: { pressed: null } // removes pressed from the result
202
+ fill: { disabled: false } // tombstone — no CSS for disabled, blocks recipe too
203
+ ```
204
+
205
+ ### Resetting Properties with `null` and `false`
206
+
207
+ ```jsx
208
+ const SimpleButton = tasty(Button, {
209
+ styles: {
210
+ fill: null, // discard parent's fill, let recipe fill in
211
+ border: false, // no border at all (tombstone — blocks recipe too)
212
+ },
213
+ });
214
+ ```
215
+
216
+ | Value | Meaning | Recipe fills in? |
217
+ |-------|---------|-----------------|
218
+ | `undefined` | Not provided — parent preserved | N/A |
219
+ | `null` | Intentional unset — parent discarded | Yes |
220
+ | `false` | Tombstone — blocks everything | No |
221
+
222
+ ---
223
+
224
+ ## Advanced States (`@` prefix)
327
225
 
328
226
  | Prefix | Purpose | Example |
329
227
  |--------|---------|---------|
@@ -339,7 +237,156 @@ const Custom = tasty({
339
237
  | `:not()` | CSS `:not()` negation (prefer `!:is()`) | `:not(:first-child)` |
340
238
  | `:where()` | CSS `:where()` (zero specificity) | `:where(Section)` |
341
239
 
342
- #### `@parent(...)` — Parent Element States
240
+ ### `@media(...)` — Media Queries
241
+
242
+ Media queries support dimension shorthands and custom unit expansion:
243
+
244
+ | Shorthand | Expands to |
245
+ |-----------|------------|
246
+ | `w` | `width` |
247
+ | `h` | `height` |
248
+
249
+ ```jsx
250
+ fill: {
251
+ '': '#surface',
252
+ '@media(w < 768px)': '#surface-mobile',
253
+ '@media(600px <= w < 1200px)': '#surface-tablet',
254
+ '@media(prefers-color-scheme: dark)': '#surface-dark',
255
+ }
256
+ ```
257
+
258
+ | Tasty syntax | CSS output |
259
+ |--------------|------------|
260
+ | `@media(w < 768px)` | `@media (width < 768px)` |
261
+ | `@media(600px <= w < 1200px)` | `@media (600px <= width < 1200px)` |
262
+ | `@media:print` | `@media print` |
263
+ | `@media:screen` | `@media screen` |
264
+ | `@media(prefers-color-scheme: dark)` | `@media (prefers-color-scheme: dark)` |
265
+ | `@media(prefers-reduced-motion)` | `@media (prefers-reduced-motion)` |
266
+
267
+ Custom units work inside media queries: `@media(w < 40x)` → `@media (width < calc(var(--gap) * 40))`.
268
+
269
+ In practice, define state aliases via `configure({ states })` and use `@mobile` instead of writing the full query in every component.
270
+
271
+ ### `@(...)` — Container Queries
272
+
273
+ Container queries use the syntax `@(name, condition)` for named containers or `@(condition)` for the nearest ancestor container. Dimension shorthands (`w`, `h`, `is`, `bs`) are expanded the same way as `@media`.
274
+
275
+ | Shorthand | Expands to |
276
+ |-----------|------------|
277
+ | `w` | `width` |
278
+ | `h` | `height` |
279
+ | `is` | `inline-size` |
280
+ | `bs` | `block-size` |
281
+
282
+ ```jsx
283
+ const Panel = tasty({
284
+ styles: {
285
+ flow: {
286
+ '': 'column',
287
+ '@(layout, w >= 600px)': 'row',
288
+ },
289
+ },
290
+ });
291
+ ```
292
+
293
+ | Tasty syntax | CSS output |
294
+ |--------------|------------|
295
+ | `@(layout, w < 600px)` | `@container layout (width < 600px)` |
296
+ | `@(w < 600px)` | `@container (width < 600px)` |
297
+ | `@(layout, $variant=danger)` | `@container layout style(--variant: "danger")` |
298
+ | `@(layout, $compact)` | `@container layout style(--compact)` |
299
+ | `@(scroll-state(stuck: top))` | `@container scroll-state(stuck: top)` |
300
+ | `@(nav, scroll-state(stuck: top))` | `@container nav scroll-state(stuck: top)` |
301
+
302
+ Container style queries use `$prop` (boolean) or `$prop=value` syntax, which maps to CSS `style(--prop)` or `style(--prop: "value")`.
303
+
304
+ ### `@supports(...)` — Feature Queries
305
+
306
+ Feature queries test CSS property support. Use `$` as the first argument to test selector support:
307
+
308
+ | Tasty syntax | CSS output |
309
+ |--------------|------------|
310
+ | `@supports(display: grid)` | `@supports (display: grid)` |
311
+ | `@supports($, :has(*))` | `@supports selector(:has(*))` |
312
+ | `!@supports(display: grid)` | `@supports (not (display: grid))` |
313
+
314
+ ```jsx
315
+ display: {
316
+ '': 'flex',
317
+ '@supports(display: grid)': 'grid',
318
+ }
319
+ ```
320
+
321
+ ### `@root(...)` — Root Element States
322
+
323
+ Root states generate selectors on the `:root` element. They are useful for theme modes, feature flags, and other page-level conditions:
324
+
325
+ ```jsx
326
+ color: {
327
+ '': '#text',
328
+ '@root(schema=dark)': '#text-on-dark',
329
+ '@root(.premium-user)': '#gold',
330
+ }
331
+ ```
332
+
333
+ | Tasty syntax | CSS selector |
334
+ |--------------|-------------|
335
+ | `@root(schema=dark)` | `:root[data-schema="dark"]` |
336
+ | `@root(hovered)` | `:root[data-hovered]` |
337
+ | `@root(.premium-user)` | `:root.premium-user` |
338
+ | `@root([lang="en"])` | `:root[lang="en"]` |
339
+ | `!@root(schema=dark)` | `:root:not([data-schema="dark"])` |
340
+
341
+ Root conditions are prepended to the component selector: `:root[data-schema="dark"] .t0.t0 { ... }`.
342
+
343
+ ### `@own(...)` — Sub-element's Own State
344
+
345
+ By default, state keys in sub-element styles refer to the root component's state context. Use `@own(...)` when the sub-element should react to its own state:
346
+
347
+ ```jsx
348
+ const Nav = tasty({
349
+ styles: {
350
+ NavItem: {
351
+ color: {
352
+ '': '#text',
353
+ '@own(:hover)': '#primary',
354
+ '@own(:focus-visible)': '#primary',
355
+ 'selected': '#primary', // root-level modifier
356
+ },
357
+ },
358
+ },
359
+ elements: { NavItem: 'a' },
360
+ });
361
+ ```
362
+
363
+ | Tasty syntax (inside sub-element) | CSS output |
364
+ |-----------------------------------|------------|
365
+ | `@own(:hover)` | `:hover` on the sub-element selector |
366
+ | `@own(hovered)` | `[data-hovered]` on the sub-element selector |
367
+ | `@own(theme=dark)` | `[data-theme="dark"]` on the sub-element selector |
368
+
369
+ `@own()` is only valid inside sub-element styles. Using it on root styles emits a warning and is treated as a regular modifier.
370
+
371
+ ### `@starting` — Entry Animation
372
+
373
+ Wraps the rule in `@starting-style`, enabling CSS entry animations for elements as they appear in the DOM:
374
+
375
+ ```jsx
376
+ const FadeIn = tasty({
377
+ styles: {
378
+ opacity: { '': '1', '@starting': '0' },
379
+ transform: { '': 'scale(1)', '@starting': 'scale(0.95)' },
380
+ transition: 'opacity 0.3s, translate 0.3s',
381
+ },
382
+ });
383
+ ```
384
+
385
+ | Tasty syntax | CSS output |
386
+ |--------------|------------|
387
+ | `@starting` | `@starting-style { .t0.t0 { ... } }` |
388
+
389
+ ### `@parent(...)` — Parent Element States
343
390
 
344
391
  Style based on ancestor element attributes. Uses `:is([selector] *)` / `:not([selector] *)` for symmetric, composable parent checks. Boolean logic (`&`, `|`, `!`) is supported inside `@parent()`.
345
392
 
@@ -381,7 +428,7 @@ const Card = tasty({
381
428
  // → .t0.t0:is([data-hovered] *) [data-element="Label"]
382
429
  ```
383
430
 
384
- #### `:is()`, `:has()` — CSS Structural Pseudo-classes
431
+ ### `:is()`, `:has()` — CSS Structural Pseudo-classes
385
432
 
386
433
  Use CSS structural pseudo-classes directly in state keys. Capitalized words become `[data-element="..."]` selectors; lowercase words are HTML tags. A trailing combinator (`>`, `+`, `~`) is auto-completed with `*`.
387
434
 
@@ -431,15 +478,9 @@ Combine with other states using boolean logic:
431
478
 
432
479
  ---
433
480
 
434
- ## Style Properties
435
-
436
- For a complete reference of all enhanced style properties — syntax, values, modifiers, and recommendations — see **[Style Properties Reference](styles.md)**.
481
+ ## Keyframes
437
482
 
438
- ---
439
-
440
- ## Advanced Features
441
-
442
- ### Keyframes
483
+ Define animations inline using the `@keyframes` key in styles:
443
484
 
444
485
  ```jsx
445
486
  const Pulse = tasty({
@@ -455,7 +496,9 @@ const Pulse = tasty({
455
496
  });
456
497
  ```
457
498
 
458
- ### Properties (`@property`)
499
+ ---
500
+
501
+ ## Properties (`@property`)
459
502
 
460
503
  CSS cannot transition or animate custom properties unless the browser knows their type. Tasty solves this automatically — when you assign a concrete value to a custom property, the type is inferred and a CSS `@property` rule is registered behind the scenes:
461
504
 
@@ -480,216 +523,18 @@ Use explicit `@properties` when you need non-default settings like `inherits: fa
480
523
  },
481
524
  ```
482
525
 
483
- ### Variants & Theming
484
-
485
- ```jsx
486
- const Button = tasty({
487
- styles: {
488
- padding: '2x 4x',
489
- border: true,
490
- },
491
- variants: {
492
- default: { fill: '#blue', color: '#white' },
493
- danger: { fill: '#red', color: '#white' },
494
- outline: { fill: 'transparent', color: '#blue', border: '1bw solid #blue' },
495
- },
496
- });
497
-
498
- <Button variant="danger">Delete</Button>
499
- ```
500
-
501
- #### Extending Variants with Base State Maps
502
-
503
- When base `styles` contain an extend-mode state map (an object **without** a `''` key), it is applied **after** the variant merge. This lets you add or override states across all variants without repeating yourself:
504
-
505
- ```jsx
506
- const Badge = tasty({
507
- styles: {
508
- padding: '1x 2x',
509
- // No '' key → extend mode: appended to every variant's border
510
- border: {
511
- 'type=primary': '#clear',
512
- },
513
- },
514
- variants: {
515
- primary: {
516
- border: { '': '#white.2', pressed: '#primary-text', disabled: '#clear' },
517
- fill: { '': '#white #primary', hovered: '#white #primary-text' },
518
- },
519
- secondary: {
520
- border: { '': '#primary.15', pressed: '#primary.3' },
521
- fill: '#primary.10',
522
- },
523
- },
524
- });
525
-
526
- // Both variants get 'type=primary': '#clear' appended to their border map
527
- ```
528
-
529
- Properties that are **not** extend-mode (simple values, state maps with `''`, `null`, `false`, selectors, sub-elements) merge with variants as before — the variant can fully replace them.
530
-
531
- ### Sub-element Styling
532
-
533
- Sub-elements are inner parts of a compound component, styled via capitalized keys in `styles` and identified by `data-element` attributes in the DOM.
534
-
535
- > **Best Practice:** Use the `elements` prop to declare sub-element components. This gives you typed, reusable sub-components (`Card.Title`, `Card.Content`) instead of manually writing `data-element` attributes.
536
-
537
- ```jsx
538
- const Card = tasty({
539
- styles: {
540
- padding: '4x',
541
- Title: { preset: 'h3', color: '#primary' },
542
- Content: { color: '#text' },
543
- },
544
- elements: {
545
- Title: 'h3',
546
- Content: 'div',
547
- },
548
- });
549
-
550
- // Sub-components automatically get data-element attributes
551
- <Card>
552
- <Card.Title>Card Title</Card.Title>
553
- <Card.Content>Card content</Card.Content>
554
- </Card>
555
- ```
556
-
557
- Each entry in `elements` can be a tag name string or a config object:
558
-
559
- ```jsx
560
- elements: {
561
- Title: 'h3', // shorthand: tag name only
562
- Icon: { as: 'span', qa: 'card-icon' }, // full form: tag + QA attribute
563
- }
564
- ```
565
-
566
- The sub-components produced by `elements` support `mods`, `tokens`, `isDisabled`, `isHidden`, and `isChecked` props — the same modifier interface as the root component.
567
-
568
- If you don't need sub-components (e.g., the inner elements are already rendered by a third-party library), you can still style them by key alone — just omit `elements` and apply `data-element` manually:
569
-
570
- ```jsx
571
- const Card = tasty({
572
- styles: {
573
- padding: '4x',
574
- Title: { preset: 'h3', color: '#primary' },
575
- },
576
- });
577
-
578
- <Card>
579
- <div data-element="Title">Card Title</div>
580
- </Card>
581
- ```
582
-
583
- #### Selector Affix (`$`)
584
-
585
- Control how a sub-element selector attaches to the root selector using the `$` property inside the sub-element's styles:
586
-
587
- | Pattern | Result | Description |
588
- |---------|--------|-------------|
589
- | *(none)* | ` [el]` | Descendant (default) |
590
- | `>` | `> [el]` | Direct child |
591
- | `>Body>Row>` | `> [Body] > [Row] > [el]` | Chained elements |
592
- | `::before` | `::before` | Root pseudo (no key) |
593
- | `@::before` | `[el]::before` | Pseudo on the sub-element |
594
- | `>@:hover` | `> [el]:hover` | Pseudo-class on the sub-element |
595
- | `>@.active` | `> [el].active` | Class on the sub-element |
596
-
597
- The `@` placeholder marks exactly where the `[data-element="..."]` selector is injected, allowing you to attach pseudo-classes, pseudo-elements, or class selectors directly to the sub-element instead of the root:
598
-
599
- ```jsx
600
- const List = tasty({
601
- styles: {
602
- Item: {
603
- $: '>@:last-child',
604
- border: 'none',
605
- },
606
- },
607
- });
608
- // → .t0 > [data-element="Item"]:last-child { border: none }
609
- ```
610
-
611
526
  ---
612
527
 
613
- ## Hooks
614
-
615
- ### useStyles
616
-
617
- ```tsx
618
- import { useStyles } from '@tenphi/tasty';
619
-
620
- function MyComponent() {
621
- const { className } = useStyles({
622
- padding: '2x',
623
- fill: '#surface',
624
- radius: '1r',
625
- });
626
-
627
- return <div className={className}>Styled content</div>;
628
- }
629
- ```
630
-
631
- ### useGlobalStyles
632
-
633
- ```tsx
634
- import { useGlobalStyles } from '@tenphi/tasty';
635
-
636
- function ThemeStyles() {
637
- useGlobalStyles('.card', {
638
- padding: '4x',
639
- fill: '#surface',
640
- radius: '1r',
641
- });
642
-
643
- return null;
644
- }
645
- ```
646
-
647
- ### useRawCSS
648
-
649
- ```tsx
650
- import { useRawCSS } from '@tenphi/tasty';
651
-
652
- function GlobalReset() {
653
- useRawCSS(`
654
- body { margin: 0; padding: 0; }
655
- `);
656
-
657
- return null;
658
- }
659
- ```
660
-
661
- ### useMergeStyles
662
-
663
- ```tsx
664
- import { useMergeStyles } from '@tenphi/tasty';
665
-
666
- function MyTabs({ styles, tabListStyles, prefixStyles }) {
667
- const mergedStyles = useMergeStyles(styles, {
668
- TabList: tabListStyles,
669
- Prefix: prefixStyles,
670
- });
528
+ ## Style Properties
671
529
 
672
- return <TabsElement styles={mergedStyles} />;
673
- }
674
- ```
530
+ For a complete reference of all enhanced style properties — syntax, values, modifiers, and recommendations — see **[Style Properties Reference](styles.md)**.
675
531
 
676
532
  ---
677
533
 
678
- ## Best Practices
679
-
680
- ### Do's
681
-
682
- - Use styled wrappers instead of `styles` prop directly
683
- - Use design tokens and custom units (`#text`, `2x`, `1r`)
684
- - Use semantic transition names (`theme 0.3s`)
685
- - Use `elements` prop to declare typed sub-components for compound components
686
- - Use `styleProps` for component APIs
687
- - Use `tokens` prop for dynamic values
688
-
689
- ### Don'ts
534
+ ## Learn more
690
535
 
691
- - Don't use `styles` prop directly on components
692
- - Don't use raw CSS values when tokens exist
693
- - Don't use CSS property names when Tasty alternatives exist — see [recommended props](styles.md#recommended-props)
694
- - Don't change `styles` prop at runtime (use modifiers or tokens instead)
695
- - Don't use `style` prop for custom styling (only for third-party library integration)
536
+ - **[Runtime API](runtime.md)** `tasty()` factory, component props, variants, sub-elements, hooks
537
+ - **[Methodology](methodology.md)** Recommended patterns: root + sub-elements, styleProps, tokens, wrapping
538
+ - **[Configuration](configuration.md)** Tokens, recipes, custom units, style handlers, TypeScript extensions
539
+ - **[Style Properties](styles.md)** Complete reference for all enhanced style properties
540
+ - **[Zero Runtime (tastyStatic)](tasty-static.md)** Build-time static styling with Babel plugin