fractalstyler2 0.0.2 → 0.3.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 (59) hide show
  1. package/README.md +60 -45
  2. package/dist/cli.js +54 -11
  3. package/dist/index.d.ts +32 -1
  4. package/dist/index.js +73 -4
  5. package/dist/mcp/export.d.ts +13 -0
  6. package/dist/mcp/export.js +76 -0
  7. package/dist/mcp/schemas/compile_fractals.json +20 -0
  8. package/dist/mcp/schemas/css_to_fractals.json +16 -0
  9. package/dist/mcp/schemas/generate_component.json +45 -0
  10. package/dist/mcp/schemas/get_design_tokens.json +23 -0
  11. package/dist/mcp/schemas/instructions.md +18 -0
  12. package/dist/mcp/schemas/list_fractals.json +20 -0
  13. package/dist/mcp/schemas/snap_to_tokens.json +25 -0
  14. package/dist/mcp/schemas/validate_recipe.json +16 -0
  15. package/dist/mcp/server.d.ts +7 -0
  16. package/dist/mcp/server.js +837 -0
  17. package/dist/styles/_00_tokens.sass +177 -0
  18. package/{templates/_config.sass → dist/styles/_01_config.sass} +11 -5
  19. package/dist/styles/_02_fonts.sass +13 -0
  20. package/dist/styles/_03_responsive.sass +31 -0
  21. package/dist/styles/{_atoms.sass → _04_atoms.sass} +4 -4
  22. package/{templates/_molecules.sass → dist/styles/_05_molecules.sass} +16 -12
  23. package/dist/styles/_06_recipes.sass +189 -0
  24. package/dist/styles/{_base.sass → _07_base.sass} +3 -2
  25. package/dist/styles/_08_blocks.sass +433 -0
  26. package/dist/styles/{_utilities.sass → _09_utilities.sass} +96 -16
  27. package/dist/styles/_10_layouts.sass +373 -0
  28. package/dist/styles/_11_own.sass +21 -0
  29. package/dist/styles/_fractals.sass +7 -6
  30. package/dist/styles/index.sass +14 -16
  31. package/mcp.json +11 -0
  32. package/package.json +14 -6
  33. package/plugin.json +22 -0
  34. package/skills/fractal-styler/SKILL.md +83 -0
  35. package/skills/fractal-styler/references/fractals.md +28 -0
  36. package/skills/fractal-styler/references/tokens.md +36 -0
  37. package/skills/style-migration/SKILL.md +45 -0
  38. package/templates/_00_tokens.sass +177 -0
  39. package/{dist/styles/_config.sass → templates/_01_config.sass} +11 -5
  40. package/templates/_02_fonts.sass +13 -0
  41. package/templates/_03_responsive.sass +31 -0
  42. package/templates/{_atoms.sass → _04_atoms.sass} +4 -4
  43. package/{dist/styles/_molecules.sass → templates/_05_molecules.sass} +16 -12
  44. package/templates/_06_recipes.sass +189 -0
  45. package/templates/{_base.sass → _07_base.sass} +3 -2
  46. package/templates/_08_blocks.sass +433 -0
  47. package/templates/{_utilities.sass → _09_utilities.sass} +96 -16
  48. package/templates/_10_layouts.sass +373 -0
  49. package/templates/_11_own.sass +21 -0
  50. package/templates/_fractals.sass +7 -6
  51. package/templates/index.sass +14 -16
  52. package/dist/styles/_blocks.sass +0 -88
  53. package/dist/styles/_layouts.sass +0 -108
  54. package/dist/styles/_responsive.sass +0 -43
  55. package/dist/styles/_tokens.sass +0 -127
  56. package/templates/_blocks.sass +0 -88
  57. package/templates/_layouts.sass +0 -108
  58. package/templates/_responsive.sass +0 -43
  59. package/templates/_tokens.sass +0 -127
@@ -0,0 +1,433 @@
1
+ // =============================================================================
2
+ // 08_BLOCKS — baseline semantic classes composed from fractal recipes.
3
+ // -----------------------------------------------------------------------------
4
+ // Blocks provide convenient markup classes without locking down arbitrary
5
+ // paddings or scale tokens. State is expressed via data-*/aria-* attributes.
6
+ // =============================================================================
7
+
8
+ @use 'fractals' as *
9
+
10
+ .surface
11
+ +surface(surface, null, 6)
12
+ +box(stretch, start)
13
+ &[data-role='raised']
14
+ +bg(raised)
15
+ &[data-role='bg']
16
+ +bg(bg)
17
+ &[data-role='panel']
18
+ +bg(panel)
19
+ &[data-role='popover']
20
+ +bg(popover)
21
+ &[data-role='dialog']
22
+ +bg(dialog)
23
+
24
+ .card
25
+ +card($pad: null, $radius: 6)
26
+ &[data-elevated]
27
+ +shadow(md)
28
+ > :is(footer, .card-footer, .meta-bottom)
29
+ margin-top: auto
30
+ padding-top: var(--space-xs)
31
+ border-top: 1px solid var(--border)
32
+
33
+ .panel
34
+ +surface(panel, null, 4)
35
+
36
+ .popover
37
+ +surface(popover, null, 6, md)
38
+
39
+ .dialog
40
+ +surface(dialog, null, 6, lg)
41
+
42
+ .terminal
43
+ +surface(terminal, null, 4)
44
+ font-family: var(--font-mono)
45
+ color: var(--text-inverse)
46
+
47
+ .canvas
48
+ +bg(canvas)
49
+
50
+ .badge
51
+ +badge
52
+ &[data-status='released']
53
+ color: var(--theme-color)
54
+ background: rgba(16, 185, 129, 0.1)
55
+ border-color: rgba(16, 185, 129, 0.25)
56
+ &[data-status='wip']
57
+ color: #d97706
58
+ background: rgba(245, 158, 11, 0.1)
59
+ border-color: rgba(245, 158, 11, 0.25)
60
+ &[data-status='archived']
61
+ +ink(muted)
62
+ &[data-status='planned']
63
+ color: #6366f1
64
+ background: rgba(99, 102, 241, 0.1)
65
+ border-color: rgba(99, 102, 241, 0.25)
66
+
67
+ .avatar
68
+ +center
69
+ +square(var(--avatar-size, 40px))
70
+ +radius(full)
71
+ +bg(raised)
72
+ +ink(secondary)
73
+ +border(all, var(--border))
74
+ overflow: hidden
75
+
76
+ .input
77
+ +input
78
+
79
+ .select
80
+ +select(md)
81
+ &.sm
82
+ +select(sm)
83
+ &.lg
84
+ +select(lg)
85
+
86
+ .divider
87
+ +divider
88
+
89
+ .kbd
90
+ +kbd
91
+
92
+ .button
93
+ +button(md, 4)
94
+ background: var(--bg-surface)
95
+ &.sm
96
+ +control(sm, 4)
97
+ justify-content: center
98
+ &.lg
99
+ +control(lg, 4)
100
+ justify-content: center
101
+ &.primary
102
+ background: var(--theme-color)
103
+ color: var(--text-inverse)
104
+ border-color: var(--theme-color)
105
+ &:hover
106
+ background: var(--theme-color-alt)
107
+ border-color: var(--theme-color-alt)
108
+ &.ghost
109
+ background: transparent
110
+ +ink(secondary)
111
+ border-color: var(--border)
112
+ &:hover
113
+ +bg(raised)
114
+ +ink(primary)
115
+ border-color: var(--border-subtle)
116
+ &[data-active]
117
+ +bg(bg)
118
+ +ink(primary)
119
+ border-color: var(--border-subtle)
120
+ +shadow(sm)
121
+
122
+ button.is-icon, a.is-icon
123
+ +row(center, center)
124
+ background: none
125
+ border: none
126
+ padding: 0
127
+ +ink(secondary)
128
+ cursor: pointer
129
+ text-decoration: none
130
+ transition: color 120ms ease
131
+ &:hover
132
+ +ink(primary)
133
+ svg
134
+ height: 16px
135
+ width: 16px
136
+
137
+ // --- Accordion ---------------------------------------------------------------
138
+ .accordion
139
+ +box
140
+ +border(all, var(--border))
141
+ +radius(6)
142
+ +bg(surface)
143
+ overflow: hidden
144
+
145
+ .accordion-item
146
+ +border(bottom, var(--border))
147
+ &:last-child
148
+ border-bottom: none
149
+
150
+ .accordion-trigger
151
+ +row(between, center)
152
+ width: 100%
153
+ padding: var(--space-xs) var(--space-s)
154
+ +bg(surface)
155
+ +ink(primary)
156
+ +type(sm)
157
+ +weight(500)
158
+ border: none
159
+ cursor: pointer
160
+ user-select: none
161
+ text-align: left
162
+ transition: background 120ms ease
163
+ &:hover
164
+ +bg(raised)
165
+ .accordion-icon
166
+ transition: transform 140ms ease
167
+ +ink(muted)
168
+
169
+ .accordion-item[data-open='true']
170
+ .accordion-trigger .accordion-icon
171
+ transform: rotate(180deg)
172
+ +ink(primary)
173
+
174
+ .accordion-content
175
+ +collapsible
176
+ .accordion-body
177
+ padding: 0 var(--space-s) var(--space-s) var(--space-s)
178
+ +type(sm)
179
+ +ink(secondary)
180
+ line-height: 1.6
181
+
182
+ // --- Dialog Modal ------------------------------------------------------------
183
+ dialog.dialog-modal
184
+ position: fixed
185
+ inset: 0
186
+ margin: auto
187
+ border: none
188
+ background: transparent
189
+ padding: 0
190
+ max-width: min(92vw, 520px)
191
+ width: 100%
192
+ z-index: var(--z-modal, 200)
193
+
194
+ &::backdrop
195
+ background: rgba(0, 0, 0, 0.55)
196
+ backdrop-filter: blur(4px)
197
+ -webkit-backdrop-filter: blur(4px)
198
+
199
+ > .dialog-card
200
+ +dialog-surface
201
+ +box
202
+ +gap(m)
203
+ +pad(m)
204
+
205
+ // --- Drawer ------------------------------------------------------------------
206
+ .drawer
207
+ position: fixed
208
+ top: 0
209
+ bottom: 0
210
+ z-index: var(--z-modal, 200)
211
+ width: min(85vw, 360px)
212
+ +bg(surface)
213
+ +border(all, var(--border))
214
+ +shadow(lg)
215
+ transition: transform 200ms ease-out
216
+ &.right
217
+ right: 0
218
+ transform: translateX(105%)
219
+ +border(left, var(--border))
220
+ &.left
221
+ left: 0
222
+ transform: translateX(-105%)
223
+ +border(right, var(--border))
224
+ &[data-open='true']
225
+ transform: translateX(0)
226
+
227
+ // --- Tabs --------------------------------------------------------------------
228
+ .tab-list
229
+ +row(null, center)
230
+ +gap(3xs)
231
+ +pad(3xs)
232
+ +radius(4)
233
+ +bg(raised)
234
+ width: fit-content
235
+ max-width: 100%
236
+
237
+ .tab-trigger
238
+ +row(center, center)
239
+ +px(xs)
240
+ +type(xs)
241
+ +weight(500)
242
+ +radius(3)
243
+ height: var(--control-h-sm, 26px)
244
+ border: none
245
+ background: transparent
246
+ +ink(secondary)
247
+ cursor: pointer
248
+ user-select: none
249
+ white-space: nowrap
250
+ transition: all 120ms ease
251
+ &:hover
252
+ +ink(primary)
253
+ &[data-active='true'], &[aria-selected='true']
254
+ +bg(surface)
255
+ +ink(primary)
256
+ +border(all, var(--border))
257
+ +shadow(sm)
258
+
259
+ // --- Switch ------------------------------------------------------------------
260
+ .switch-track
261
+ position: relative
262
+ display: inline-flex
263
+ align-items: center
264
+ flex-shrink: 0
265
+ width: 36px
266
+ height: 20px
267
+ +radius(full)
268
+ +bg(raised)
269
+ +border(all, var(--border))
270
+ cursor: pointer
271
+ user-select: none
272
+ padding: 2px
273
+ transition: background 140ms ease, border-color 140ms ease
274
+
275
+ &[data-checked='true']
276
+ background: var(--theme-color)
277
+ border-color: var(--theme-color)
278
+
279
+ .switch-thumb
280
+ display: block
281
+ width: 14px
282
+ height: 14px
283
+ +radius(full)
284
+ background: var(--text-primary)
285
+ transition: transform 140ms cubic-bezier(0.34, 1.56, 0.64, 1), background 140ms ease
286
+ will-change: transform
287
+
288
+ .switch-track[data-checked='true'] .switch-thumb
289
+ transform: translateX(16px)
290
+ background: var(--text-inverse)
291
+
292
+ // --- Field -------------------------------------------------------------------
293
+ .field
294
+ +box
295
+ +gap(3xs)
296
+ width: 100%
297
+
298
+ .field-label
299
+ +type(xs)
300
+ +weight(600)
301
+ text-transform: uppercase
302
+ letter-spacing: 0.05em
303
+ +ink(secondary)
304
+
305
+ .field-error
306
+ +type(xs)
307
+ color: #dc2626
308
+ margin-top: 2px
309
+
310
+ // --- Marquee -----------------------------------------------------------------
311
+ .marquee, [data-slot="marquee"]
312
+ overflow: hidden
313
+ display: flex
314
+ user-select: none
315
+ gap: var(--marquee-gap, 1rem)
316
+ position: relative
317
+ width: 100%
318
+
319
+ &[data-fade="true"]
320
+ mask-image: linear-gradient(to right, transparent 0%, black 10%, black 90%, transparent 100%)
321
+
322
+ [data-slot="marquee-track"]
323
+ display: flex
324
+ flex-shrink: 0
325
+ justify-content: space-around
326
+ gap: var(--marquee-gap, 1rem)
327
+ min-width: 100%
328
+ animation: marquee-scroll var(--marquee-speed, 30s) linear infinite
329
+
330
+ &[data-pause="true"]:hover [data-slot="marquee-track"]
331
+ animation-play-state: paused
332
+
333
+ &[data-vertical="true"]
334
+ flex-direction: column
335
+ height: 300px
336
+ &[data-fade="true"]
337
+ mask-image: linear-gradient(to bottom, transparent 0%, black 10%, black 90%, transparent 100%)
338
+ [data-slot="marquee-track"]
339
+ flex-direction: column
340
+ min-height: 100%
341
+ animation-name: marquee-scroll-vertical
342
+
343
+ @keyframes marquee-scroll
344
+ from
345
+ transform: translateX(0)
346
+ to
347
+ transform: translateX(calc(-100% - var(--marquee-gap, 1rem)))
348
+
349
+ @keyframes marquee-scroll-vertical
350
+ from
351
+ transform: translateY(0)
352
+ to
353
+ transform: translateY(calc(-100% - var(--marquee-gap, 1rem)))
354
+
355
+ // --- Animated Badge ----------------------------------------------------------
356
+ [data-slot="badge"]
357
+ position: relative
358
+ display: inline-flex
359
+ align-items: center
360
+ overflow: hidden
361
+ border: 1px solid var(--border)
362
+ border-radius: var(--radius-full)
363
+ font-weight: 500
364
+ white-space: nowrap
365
+ color: var(--text-secondary)
366
+ background: var(--bg-surface)
367
+
368
+ &[data-size="sm"]
369
+ height: 1.5rem
370
+ gap: var(--space-3xs)
371
+ padding: 0 var(--space-2xs)
372
+ font-size: var(--text-xs)
373
+ &[data-size="md"]
374
+ height: 1.75rem
375
+ gap: var(--space-2xs)
376
+ padding: 0 var(--space-xs)
377
+ font-size: var(--text-xs)
378
+
379
+ &[data-status="info"], &[data-status="loading"]
380
+ border-color: var(--theme-color)
381
+ color: var(--theme-color)
382
+ background: var(--bg-raised)
383
+ &[data-status="success"]
384
+ border-color: #10b981
385
+ color: #10b981
386
+ &[data-status="warning"]
387
+ border-color: #f59e0b
388
+ color: #f59e0b
389
+ &[data-status="danger"]
390
+ border-color: #ef4444
391
+ color: #ef4444
392
+
393
+ [data-slot="badge-icon"], [data-slot="badge-label"]
394
+ position: relative
395
+ z-index: 1
396
+ display: inline-flex
397
+ animation: badge-roll 0.42s cubic-bezier(0.16, 1, 0.3, 1)
398
+
399
+ [data-slot="badge-icon"]
400
+ align-items: center
401
+ justify-content: center
402
+
403
+ [data-status="loading"] [data-slot="badge-icon"]
404
+ animation: badge-spin 1s linear infinite
405
+
406
+ [data-slot="badge-pulse"]
407
+ position: absolute
408
+ inset: 0
409
+ border-radius: inherit
410
+ background: currentColor
411
+ animation: badge-pulse 1.6s ease-in-out infinite
412
+
413
+ @keyframes badge-roll
414
+ from
415
+ transform: translateY(80%)
416
+ opacity: 0
417
+ filter: blur(4px)
418
+
419
+ @keyframes badge-spin
420
+ to
421
+ transform: rotate(360deg)
422
+
423
+ @keyframes badge-pulse
424
+ 0%, 100%
425
+ opacity: 0.08
426
+ transform: scale(0.94)
427
+ 50%
428
+ opacity: 0.18
429
+ transform: scale(1.08)
430
+
431
+ @media (prefers-reduced-motion: reduce)
432
+ [data-slot="badge-icon"], [data-slot="badge-label"], [data-slot="badge-pulse"], [data-slot="marquee-track"]
433
+ animation: none !important
@@ -1,17 +1,14 @@
1
1
  // =============================================================================
2
- // UTILITY PROJECTION — the *other* way to consume a fractal.
2
+ // 09_UTILITIES — the markup projection of atom & molecule fractals.
3
3
  // -----------------------------------------------------------------------------
4
- // A fractal is a mixin. Here we bind a subset of them to class names so they
5
- // stay usable straight from markup (`class="box gap-m pad-l"`). This is the
6
- // key idea: utility classes are not a separate system they are a generated
7
- // projection of the exact same fractals your components compose. Emit only the
8
- // atoms you want in markup; delete this whole file if you go SASS-only.
4
+ // Every utility class here is a direct 1:1 projection of an atom or molecule
5
+ // mixin. Because this file is loaded after _08_blocks.sass in index.sass, utility
6
+ // classes can be used on any element to set or override properties without
7
+ // specificity wars.
9
8
  // =============================================================================
10
9
 
11
- @use 'config' as *
12
- @use 'atoms' as *
13
- @use 'molecules' as *
14
- @use 'responsive' as *
10
+ @use 'sass:string'
11
+ @use 'fractals' as *
15
12
 
16
13
  // --- Flow ------------------------------------------------------------------
17
14
  .box
@@ -35,6 +32,10 @@
35
32
  justify-content: flex-start
36
33
  &.ybot
37
34
  justify-content: flex-end
35
+ &.ybetween
36
+ justify-content: space-between
37
+ &.yevenly
38
+ justify-content: space-evenly
38
39
 
39
40
  .row
40
41
  &.ycenter
@@ -60,7 +61,27 @@
60
61
  .center
61
62
  +center
62
63
 
63
- // --- Spacing scale → gap-* / pad-* -----------------------------------------
64
+ // --- Molecule Projections --------------------------------------------------
65
+ .stack
66
+ +stack(s)
67
+
68
+ .cluster
69
+ +cluster(xs)
70
+
71
+ .frame
72
+ +frame('16 / 9')
73
+ &.square
74
+ +frame('1 / 1')
75
+ &.video
76
+ +frame('16 / 9')
77
+
78
+ .reel
79
+ +reel(s)
80
+
81
+ .center-column
82
+ +center-column
83
+
84
+ // --- Spacing scale → gap-* / pad-* / margin-* ------------------------------
64
85
  @each $s in $space-steps
65
86
  .gap-#{$s}
66
87
  +gap($s)
@@ -70,6 +91,29 @@
70
91
  +px($s)
71
92
  .py-#{$s}
72
93
  +py($s)
94
+ .pad-top-#{$s}, .pt-#{$s}
95
+ padding-top: space($s)
96
+ .pad-bottom-#{$s}, .pb-#{$s}
97
+ padding-bottom: space($s)
98
+ .pad-left-#{$s}, .pl-#{$s}
99
+ padding-left: space($s)
100
+ .pad-right-#{$s}, .pr-#{$s}
101
+ padding-right: space($s)
102
+ .m-#{$s}
103
+ margin: space($s)
104
+ .mx-#{$s}
105
+ margin-inline: space($s)
106
+ .my-#{$s}
107
+ margin-block: space($s)
108
+ .mt-#{$s}, .margin-top-#{$s}
109
+ margin-top: space($s)
110
+ .mb-#{$s}, .margin-bottom-#{$s}
111
+ margin-bottom: space($s)
112
+
113
+ .mx-auto
114
+ +mx-auto
115
+ .my-auto
116
+ +my-auto
73
117
 
74
118
  // --- Radius / shadow / surface ---------------------------------------------
75
119
  @each $r in $radius-steps
@@ -98,11 +142,22 @@
98
142
  .truncate
99
143
  +truncate
100
144
 
101
- // Semantic type primitives — so you stop retyping `.text-sm .lh15 .muted`.
102
- .body
103
- +type(md)
104
- +leading(1.6)
105
- +ink(primary)
145
+ .clamp-1
146
+ +clamp-lines(1)
147
+ .clamp-2
148
+ +clamp-lines(2)
149
+ .clamp-3
150
+ +clamp-lines(3)
151
+
152
+ .weight-400
153
+ +weight(400)
154
+ .weight-500
155
+ +weight(500)
156
+ .weight-600
157
+ +weight(600)
158
+ .weight-700
159
+ +weight(700)
160
+
106
161
  .muted
107
162
  +ink(secondary)
108
163
  .eyebrow
@@ -121,5 +176,30 @@
121
176
  +full
122
177
  .grow
123
178
  +grow
179
+ .shrink-0
180
+ +shrink(0)
124
181
  .min0
125
182
  +min0
183
+ .relative
184
+ +relative
185
+ .absolute
186
+ +absolute
187
+ .overflow-hidden
188
+ overflow: hidden
189
+ .cursor-pointer
190
+ cursor: pointer
191
+ .block
192
+ display: block
193
+
194
+ // --- Responsive Visibility -------------------------------------------------
195
+ .hide-desktop
196
+ +at(lg)
197
+ display: none !important
198
+
199
+ .hide-mobile
200
+ +below(lg)
201
+ display: none !important
202
+
203
+ .only-mobile
204
+ +at(lg)
205
+ display: none !important