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,373 @@
1
+ // =============================================================================
2
+ // 10_LAYOUTS — the largest fractals. Same recipe move, page scale.
3
+ // -----------------------------------------------------------------------------
4
+ // Layouts compose molecule and atom fractals into structural arrangements.
5
+ // State and responsive reflow are handled with +cols, +auto-grid, +cover.
6
+ // =============================================================================
7
+
8
+ @use 'fractals' as *
9
+
10
+ // Column grid presets
11
+ .grid-1
12
+ +cols((base: 1), s)
13
+
14
+ .grid-2
15
+ +cols((base: 1, md: 2), m)
16
+
17
+ .grid-3
18
+ +cols((base: 1, sm: 2, lg: 3), s)
19
+
20
+ .grid-4
21
+ +cols((base: 1, sm: 2, lg: 4), s)
22
+
23
+ .grid-6
24
+ +cols((base: 2, sm: 3, md: 4, lg: 6), xs)
25
+
26
+ // A grid that never needs breakpoints: it fits as many columns as will hold
27
+ // the min track. Reach for this when column count is negotiable.
28
+ .card-grid
29
+ +auto-grid(16rem, s)
30
+
31
+ // Hero — full-viewport cover with a centered, measured message.
32
+ .hero
33
+ +cover(80vh, xl)
34
+ > .center
35
+ +stack(m, center)
36
+ text-align: center
37
+ max-width: 45ch
38
+
39
+ // Holy grail — header / (nav · main · aside) / footer.
40
+ .holy-grail
41
+ display: grid
42
+ min-height: 100vh
43
+ grid-template-rows: auto 1fr auto
44
+ grid-template-areas: 'header' 'main' 'footer'
45
+ > .hg-header
46
+ grid-area: header
47
+ > .hg-footer
48
+ grid-area: footer
49
+ > .hg-body
50
+ grid-area: main
51
+ display: grid
52
+ grid-template-columns: 1fr
53
+ +gap(m)
54
+ +pad(m)
55
+ +at(lg)
56
+ > .hg-body
57
+ grid-template-columns: var(--nav-w, 220px) minmax(0, 1fr) var(--aside-w, 260px)
58
+ > .hg-nav
59
+ +sticky(var(--space-m))
60
+ align-self: start
61
+ > .hg-aside
62
+ +sticky(var(--space-m))
63
+ align-self: start
64
+
65
+ // Docs layout — responsive 3-column frame (nav · main · TOC).
66
+ .docs
67
+ position: relative
68
+ display: grid
69
+ grid-template-columns: 1fr
70
+ min-height: calc(100vh - var(--header-height, 48px))
71
+
72
+ // Left Nav Rail (off-canvas drawer on mobile, sticky rail on desktop)
73
+ > .docs-nav
74
+ position: fixed
75
+ top: var(--header-height, 48px)
76
+ left: 0
77
+ z-index: var(--z-modal, 200)
78
+ width: min(85vw, 280px)
79
+ height: calc(100dvh - var(--header-height, 48px))
80
+ padding: var(--space-s)
81
+ overflow-y: auto
82
+ background: var(--bg)
83
+ +border(right)
84
+ transform: translateX(-105%)
85
+ transition: transform 200ms ease-out
86
+
87
+ &[data-drawer-open='true'] > .docs-nav
88
+ transform: translateX(0)
89
+
90
+ // Backdrop for mobile drawer
91
+ > .docs-backdrop
92
+ position: fixed
93
+ inset: var(--header-height, 48px) 0 0 0
94
+ z-index: calc(var(--z-modal, 200) - 1)
95
+ background: rgba(0, 0, 0, 0.5)
96
+ backdrop-filter: blur(2px)
97
+ border: none
98
+ cursor: pointer
99
+
100
+ // Center Reading Column
101
+ > .docs-main
102
+ +min0
103
+ +box
104
+ padding-block: var(--space-l)
105
+ padding-inline: var(--space-s)
106
+ > *
107
+ width: 100%
108
+ max-width: clamp(600px, 58vw, 760px)
109
+ margin-inline: auto
110
+
111
+ // Right TOC Rail (desktop only)
112
+ > .docs-toc
113
+ display: none
114
+
115
+ // Desktop Breakpoint (>= 1024px)
116
+ +at(lg)
117
+ --docs-nav-w: clamp(220px, 20vw, 270px)
118
+ --docs-toc-w: clamp(200px, 18vw, 240px)
119
+ grid-template-columns: var(--docs-nav-w) minmax(0, 1fr) var(--docs-toc-w)
120
+
121
+ > .docs-nav
122
+ position: sticky
123
+ top: var(--header-height, 48px)
124
+ width: auto
125
+ height: calc(100vh - var(--header-height, 48px))
126
+ transform: none
127
+ z-index: 10
128
+ padding: var(--space-m) var(--space-s)
129
+
130
+ > .docs-toc
131
+ display: block
132
+ position: sticky
133
+ top: var(--header-height, 48px)
134
+ height: calc(100vh - var(--header-height, 48px))
135
+ overflow-y: auto
136
+ padding: var(--space-m) var(--space-s)
137
+ +border(left)
138
+
139
+ > .docs-backdrop
140
+ display: none
141
+
142
+ // NavTree styling
143
+ .navtree
144
+ +box
145
+ +gap(m)
146
+
147
+ .navtree-group
148
+ +box
149
+ +gap(3xs)
150
+
151
+ .navtree-title
152
+ font-size: var(--text-xs)
153
+ font-weight: 600
154
+ text-transform: uppercase
155
+ letter-spacing: 0.06em
156
+ color: var(--text-muted)
157
+ padding: 6px 8px
158
+
159
+ .navtree-link
160
+ +row(between, center)
161
+ padding: 6px 10px
162
+ font-size: var(--text-sm)
163
+ color: var(--text-secondary)
164
+ border-radius: var(--radius-4)
165
+ text-decoration: none
166
+ transition: all 120ms ease
167
+ &:hover
168
+ +bg(raised)
169
+ +ink(primary)
170
+ &[aria-current='page'], &[data-active='true']
171
+ +bg(surface)
172
+ color: var(--theme)
173
+ font-weight: 500
174
+ +border
175
+
176
+ .navtree-sub
177
+ +box
178
+ +gap(3xs)
179
+ margin-left: 12px
180
+ padding-left: 8px
181
+ +border(left)
182
+
183
+ // TOC styling
184
+ .toc
185
+ +box
186
+ +gap(m)
187
+ height: 100%
188
+
189
+ .toc-title
190
+ font-size: var(--text-xs)
191
+ font-weight: 600
192
+ text-transform: uppercase
193
+ letter-spacing: 0.06em
194
+ color: var(--text-muted)
195
+
196
+ .toc-list
197
+ list-style: none
198
+ margin: 0
199
+ padding: 0
200
+ +box
201
+ +gap(2xs)
202
+
203
+ .toc-link
204
+ display: block
205
+ font-size: var(--text-xs)
206
+ color: var(--text-muted)
207
+ text-decoration: none
208
+ padding: 3px 0
209
+ transition: color 120ms ease
210
+ &:hover
211
+ +ink(primary)
212
+ &[aria-current='true']
213
+ color: var(--theme)
214
+ font-weight: 500
215
+ &[data-depth='3']
216
+ padding-left: 10px
217
+
218
+ .toc-footer
219
+ +partition(top, s)
220
+ +box
221
+ +gap(2xs)
222
+
223
+ // Mobile TOC Disclosure
224
+ .docs-mobile-toc
225
+ +box
226
+ +gap(xs)
227
+ +pad(xs)
228
+ +radius(6)
229
+ +bg(surface)
230
+ +border(all, var(--border))
231
+ summary
232
+ +row(between, center)
233
+ +weight(500)
234
+ +type(sm)
235
+ +ink(primary)
236
+ cursor: pointer
237
+ user-select: none
238
+ list-style: none
239
+ &::-webkit-details-marker
240
+ display: none
241
+ &[open]
242
+ +bg(raised)
243
+ summary
244
+ margin-bottom: var(--space-xs)
245
+ padding-bottom: var(--space-2xs)
246
+ +border(bottom, var(--border))
247
+
248
+ // Prose Typography Container
249
+ .prose
250
+ font-size: var(--text-sm)
251
+ line-height: 1.65
252
+ color: var(--text-secondary)
253
+
254
+ > * + *
255
+ margin-top: 1rem
256
+
257
+ h1
258
+ font-size: var(--text-3xl)
259
+ font-weight: 700
260
+ color: var(--text-primary)
261
+ line-height: 1.2
262
+ margin-top: 0
263
+ margin-bottom: 0.5rem
264
+
265
+ h2
266
+ font-size: var(--text-xl)
267
+ font-weight: 600
268
+ color: var(--text-primary)
269
+ line-height: 1.3
270
+ margin-top: 2rem
271
+ margin-bottom: 0.5rem
272
+ padding-bottom: 0.25rem
273
+ +border(bottom)
274
+
275
+ h3
276
+ font-size: var(--text-md)
277
+ font-weight: 600
278
+ color: var(--text-primary)
279
+ margin-top: 1.5rem
280
+ margin-bottom: 0.25rem
281
+
282
+ h4
283
+ font-size: var(--text-sm)
284
+ font-weight: 600
285
+ color: var(--text-primary)
286
+
287
+ p
288
+ margin-bottom: 1rem
289
+
290
+ ul, ol
291
+ padding-left: 1.25rem
292
+ margin-bottom: 1rem
293
+ li
294
+ margin-bottom: 0.25rem
295
+
296
+ code:not(pre code)
297
+ font-family: var(--font-mono)
298
+ font-size: 0.85em
299
+ padding: 2px 6px
300
+ background: var(--bg-raised)
301
+ border: 1px solid var(--border)
302
+ border-radius: var(--radius-3)
303
+ color: var(--text-primary)
304
+
305
+ pre
306
+ position: relative
307
+ background: var(--bg-surface)
308
+ border: 1px solid var(--border)
309
+ border-radius: var(--radius-6)
310
+ padding: var(--space-s)
311
+ overflow-x: auto
312
+ font-family: var(--font-mono)
313
+ font-size: var(--text-xs)
314
+ line-height: 1.5
315
+ color: var(--text-primary)
316
+ code
317
+ font-family: inherit
318
+ font-size: inherit
319
+ background: none
320
+ border: none
321
+ padding: 0
322
+
323
+ table
324
+ width: 100%
325
+ border-collapse: collapse
326
+ margin-block: 1.25rem
327
+ font-size: var(--text-sm)
328
+ th
329
+ text-align: left
330
+ padding: 8px 12px
331
+ border-bottom: 1px solid var(--border-subtle)
332
+ font-size: var(--text-xs)
333
+ font-weight: 600
334
+ text-transform: uppercase
335
+ letter-spacing: 0.04em
336
+ color: var(--text-primary)
337
+ td
338
+ padding: 8px 12px
339
+ border-bottom: 1px solid var(--border)
340
+ color: var(--text-secondary)
341
+
342
+ blockquote
343
+ margin: 1.25rem 0
344
+ padding: 8px 16px
345
+ border-left: 3px solid var(--theme)
346
+ background: var(--bg-raised)
347
+ border-radius: 0 var(--radius-4) var(--radius-4) 0
348
+ p
349
+ margin: 0
350
+ color: var(--text-primary)
351
+
352
+ // App shell — sticky header, fluid body, footer.
353
+ .app-shell
354
+ +box
355
+ +relative
356
+ isolation: isolate
357
+ min-height: 100vh
358
+ > .app-header
359
+ +row(null, center)
360
+ +sticky(0)
361
+ +px(m)
362
+ background: var(--bg)
363
+ z-index: var(--z-sticky)
364
+ height: var(--header-height)
365
+ +border(bottom)
366
+ > .app-main
367
+ +grow
368
+ +min0
369
+ > .app-footer
370
+ +row(null, center)
371
+ +px(m)
372
+ min-height: var(--footer-height)
373
+ +border(top)
@@ -0,0 +1,21 @@
1
+ // =============================================================================
2
+ // 11_OWN — bespoke project-specific styles and micro-components.
3
+ // =============================================================================
4
+
5
+ @use 'fractals' as *
6
+
7
+ .logomotif
8
+ height: 28px
9
+ width: 28px
10
+ filter: saturate(0)
11
+
12
+ .logotype
13
+ height: 16px
14
+ filter: saturate(0)
15
+
16
+ .header-nav
17
+ font-size: var(--text-sm)
18
+ text-decoration: none
19
+ color: var(--text-secondary)
20
+ &:hover
21
+ color: var(--theme-color)
@@ -1,13 +1,14 @@
1
1
  // =============================================================================
2
- // FRACTALS — the pure API barrel. Emits NO css on its own.
2
+ // FRACTALS — the pure API barrel. Emits NO CSS on its own.
3
3
  // -----------------------------------------------------------------------------
4
4
  // In any component partial or Svelte component:
5
5
  // @use '$lib/styles/fractals' as *
6
6
  // (or @use './fractals' as *)
7
- // then call fractals freely: +surface(...) +stack(...) space(m) ...
7
+ // then call fractals freely: +surface(...) +stack(...) +card(...)
8
8
  // =============================================================================
9
9
 
10
- @forward 'config'
11
- @forward 'responsive'
12
- @forward 'atoms'
13
- @forward 'molecules'
10
+ @forward '01_config'
11
+ @forward '03_responsive'
12
+ @forward '04_atoms'
13
+ @forward '05_molecules'
14
+ @forward '06_recipes'
@@ -1,20 +1,18 @@
1
1
  // =============================================================================
2
- // STYLES ENTRY the full emitted stylesheet in cascade order.
2
+ // FRACTALSTYLER2Master Stylesheet & Public Mixin API
3
3
  // -----------------------------------------------------------------------------
4
- // 1. tokens the CSS custom properties (only literal values)
5
- // 2. base fluid reset
6
- // 3. utilities atom fractals projected to markup classes (optional layer)
7
- // 4. blocks components composed from fractals
8
- // 5. layouts page templates composed from fractals
9
- //
10
- // Consume from a SvelteKit app: import '$lib/styles/index.sass'
11
- // or from package: import 'fractalstyler2/styles'
12
- // The fractal mixins/functions themselves emit nothing until called, so output
13
- // contains only what you use.
4
+ // 1. Public API: Forwards all pure mixins, functions, and atoms (0 bytes CSS)
5
+ // 2. Cascade Order: Emits CSS rules in strict specificity sequence
14
6
  // =============================================================================
15
7
 
16
- @use './tokens'
17
- @use './base'
18
- @use './utilities'
19
- @use './blocks'
20
- @use './layouts'
8
+ // Public Sass API — available to any file that @uses this module
9
+ @forward 'fractals'
10
+
11
+ // Global Stylesheet Cascade
12
+ @use '02_fonts' as *
13
+ @use '00_tokens' as *
14
+ @use '07_base' as *
15
+ @use '08_blocks' as *
16
+ @use '09_utilities' as *
17
+ @use '10_layouts' as *
18
+ @use '11_own' as *
@@ -1,88 +0,0 @@
1
- // =============================================================================
2
- // BLOCKS — components as recipes of fractals. Note how little CSS is here:
3
- // each block is a handful of fractal calls plus its own genuinely-unique lines.
4
- // State is expressed with data-*/aria-*, never modifier classes.
5
- // =============================================================================
6
-
7
- @use 'fractals' as *
8
-
9
- .card
10
- +surface(surface, s, 12)
11
- +stack(s)
12
- &[data-elevated]
13
- +shadow(md)
14
-
15
- .panel
16
- +surface(raised, m, 16)
17
- +stack(m)
18
-
19
- .badge
20
- +row(center, center)
21
- display: inline-flex
22
- +px(2xs)
23
- +type(xs)
24
- +weight(500)
25
- +radius(full)
26
- +bg(raised)
27
- +ink(secondary)
28
- padding-block: 2px
29
-
30
- .avatar
31
- +center
32
- +square(var(--avatar-size, 40px))
33
- +radius(full)
34
- +bg(raised)
35
- +ink(secondary)
36
- overflow: hidden
37
-
38
- .input
39
- display: block
40
- +w(100%)
41
- +px(2xs)
42
- +type(md)
43
- +leading(1.5)
44
- +border
45
- +radius(6)
46
- +bg(bg)
47
- +ink(primary)
48
- padding-block: 8px
49
- &:focus-visible
50
- +ring
51
-
52
- .button
53
- +row(center, center)
54
- +gap(2xs)
55
- +px(s)
56
- +radius(6)
57
- +weight(500)
58
- +transition(background-color)
59
- cursor: pointer
60
- padding-block: 8px
61
- user-select: none
62
- // Exceptions: variants live on data-variant, not in the class name.
63
- &[data-variant='primary']
64
- background: var(--theme)
65
- color: var(--text-inverse)
66
- &:hover
67
- background: var(--theme-hover)
68
- &[data-variant='ghost']
69
- background: transparent
70
- +ink(secondary)
71
- &:hover
72
- +bg(raised)
73
-
74
- .divider
75
- border: none
76
- +border(top)
77
- margin-block: space(s)
78
-
79
- .kbd
80
- display: inline-block
81
- +px(3xs)
82
- +type(xs)
83
- +leading(1)
84
- +radius(4)
85
- +bg(raised)
86
- border: 1px solid var(--border-strong)
87
- font-family: var(--font-mono)
88
- padding-block: 2px
@@ -1,108 +0,0 @@
1
- // =============================================================================
2
- // LAYOUTS — the largest fractals. Same recipe move, page scale.
3
- // These are the concrete deliverables you named: a responsive 3-col grid, a
4
- // hero, a holy-grail, a docs template. Each is a short composition of fractals.
5
- // =============================================================================
6
-
7
- @use 'fractals' as *
8
-
9
- // 1. Responsive grid of 3 columns — 1 → 2 → 3 across breakpoints.
10
- .grid-3
11
- +cols((base: 1, sm: 2, lg: 3), m)
12
-
13
- // A grid that never needs breakpoints: it fits as many columns as will hold
14
- // the min track. Reach for this before .grid-3 when column count is negotiable.
15
- .card-grid
16
- +auto-grid(16rem, m)
17
-
18
- // 2. Hero — full-viewport cover with a centered, measured message.
19
- .hero
20
- +cover(80vh, xl)
21
- > .center
22
- +stack(m, center)
23
- text-align: center
24
- max-width: 45ch
25
-
26
- // 3. Holy grail — header / (nav · main · aside) / footer.
27
- .holy-grail
28
- display: grid
29
- min-height: 100vh
30
- grid-template-rows: auto 1fr auto
31
- grid-template-areas: 'header' 'main' 'footer'
32
- > .hg-header
33
- grid-area: header
34
- > .hg-footer
35
- grid-area: footer
36
- > .hg-body
37
- grid-area: main
38
- display: grid
39
- grid-template-columns: 1fr
40
- +gap(m)
41
- +pad(m)
42
- +at(lg)
43
- > .hg-body
44
- grid-template-columns: var(--nav-w, 220px) minmax(0, 1fr) var(--aside-w, 260px)
45
- > .hg-nav
46
- +sticky(var(--space-m))
47
- align-self: start
48
- > .hg-aside
49
- +sticky(var(--space-m))
50
- align-self: start
51
-
52
- // 4. Docs template — sidebar nav + reading column + on-page TOC.
53
- .docs
54
- display: grid
55
- min-height: 100vh
56
- grid-template-columns: 1fr
57
- > .docs-nav
58
- display: none
59
- > .docs-toc
60
- display: none
61
- > .docs-main
62
- +min0
63
- +stack(m)
64
- +center-column(72ch, s-l)
65
- +py(l)
66
- +at(md)
67
- grid-template-columns: var(--docs-nav-w, 240px) minmax(0, 1fr)
68
- > .docs-nav
69
- +box
70
- +sticky(0)
71
- +py(l)
72
- +px(s)
73
- height: 100vh
74
- overflow-y: auto
75
- +border(right)
76
- +at(xl)
77
- grid-template-columns: var(--docs-nav-w, 240px) minmax(0, 1fr) var(--docs-toc-w, 220px)
78
- > .docs-toc
79
- +box
80
- +sticky(0)
81
- +py(l)
82
- +px(s)
83
- height: 100vh
84
- overflow-y: auto
85
- +ink(secondary)
86
-
87
- // 5. App shell — sticky header, fluid body, footer. The frame most apps live in.
88
- .app-shell
89
- +box
90
- +relative
91
- isolation: isolate
92
- min-height: 100vh
93
- > .app-header
94
- +row(null, center)
95
- +sticky(0)
96
- +px(m)
97
- z-index: var(--z-sticky)
98
- height: var(--header-height)
99
- +bg(surface)
100
- +border(bottom)
101
- > .app-main
102
- +grow
103
- +min0
104
- > .app-footer
105
- +row(null, center)
106
- +px(m)
107
- min-height: var(--footer-height)
108
- +border(top)
@@ -1,43 +0,0 @@
1
- // =============================================================================
2
- // RESPONSIVE FRACTALS — the units that let any other fractal grow with the page.
3
- // -----------------------------------------------------------------------------
4
- // These are self-similar too: +at(md) wraps any block of fractal calls in a
5
- // breakpoint, so a "responsive component" is just a component whose fractals
6
- // are re-stated inside +at(...).
7
- // =============================================================================
8
-
9
- @use 'sass:map'
10
- @use 'config' as *
11
-
12
- // +at(md) — mobile-first min-width query by name (sm/md/lg/xl) or raw length.
13
- =at($name)
14
- $edge: $name
15
- @if map.has-key($breakpoints, $name)
16
- $edge: bp($name)
17
- @media (min-width: #{$edge})
18
- @content
19
-
20
- // +until(md) — max-width query (one below the named edge).
21
- =until($name)
22
- $edge: $name
23
- @if map.has-key($breakpoints, $name)
24
- $edge: bp($name)
25
- @media (max-width: #{$edge})
26
- @content
27
-
28
- // Container-query fractals — component-scoped responsiveness.
29
- =cq
30
- container-type: inline-size
31
-
32
- =cq-at($width)
33
- @container (min-width: #{$width})
34
- @content
35
-
36
- =cq-until($width)
37
- @container (max-width: #{$width})
38
- @content
39
-
40
- // Motion / preference-aware fractal.
41
- =reduce-motion
42
- @media (prefers-reduced-motion: reduce)
43
- @content