gerillass 0.0.6 → 3.0.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 (121) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +13 -0
  3. data/README.md +328 -0
  4. data/SKILL.md +282 -0
  5. data/gerillass.json +2713 -0
  6. data/lib/gerillass/engine.rb +55 -0
  7. data/lib/gerillass/jekyll.rb +13 -0
  8. data/lib/gerillass.rb +26 -0
  9. data/scss/_gerillass.scss +15 -0
  10. data/scss/internal/_color-problem.scss +99 -0
  11. data/scss/internal/_color-stops-problem.scss +94 -0
  12. data/scss/internal/_condition-width.scss +22 -0
  13. data/scss/internal/_custom-property-in.scss +25 -0
  14. data/scss/internal/_gradient.scss +425 -0
  15. data/scss/internal/_image-value.scss +68 -0
  16. data/scss/internal/_is-condition-value.scss +94 -0
  17. data/scss/internal/_is-css-function.scss +21 -0
  18. data/scss/internal/_is-size.scss +22 -0
  19. data/scss/internal/_keyword-value.scss +76 -0
  20. data/scss/internal/_length-problem.scss +127 -0
  21. data/scss/internal/_sibling-index.scss +51 -0
  22. data/scss/internal/_words.scss +35 -0
  23. data/scss/library/_adaptive.scss +31 -0
  24. data/scss/library/_after.scss +28 -0
  25. data/scss/library/_all-buttons.scss +21 -0
  26. data/scss/library/_all-text-inputs.scss +21 -0
  27. data/{core → scss}/library/_antialias.scss +5 -1
  28. data/scss/library/_aspect-ratio.scss +27 -0
  29. data/scss/library/_background-dots.scss +104 -0
  30. data/scss/library/_background-image.scss +89 -0
  31. data/scss/library/_background-stripes.scss +88 -0
  32. data/scss/library/_before.scss +28 -0
  33. data/scss/library/_border-box.scss +30 -0
  34. data/scss/library/_border-radius.scss +164 -0
  35. data/scss/library/_brand-logo.scss +33 -0
  36. data/scss/library/_breakpoint.scss +96 -0
  37. data/scss/library/_breakpointer.scss +40 -0
  38. data/scss/library/_center.scss +19 -0
  39. data/scss/library/_circle.scss +15 -0
  40. data/{core → scss}/library/_clearfix.scss +1 -1
  41. data/scss/library/_columnizer.scss +125 -0
  42. data/scss/library/_container-query.scss +119 -0
  43. data/scss/library/_container.scss +72 -0
  44. data/scss/library/_counter.scss +59 -0
  45. data/scss/library/_ellipsis.scss +87 -0
  46. data/scss/library/_escape-to-parent.scss +12 -0
  47. data/scss/library/_except.scss +71 -0
  48. data/scss/library/_focus-ring.scss +63 -0
  49. data/scss/library/_font-face.scss +240 -0
  50. data/scss/library/_gradient.scss +31 -0
  51. data/scss/library/_hide.scss +25 -0
  52. data/scss/library/_index.scss +57 -0
  53. data/scss/library/_line-clamp.scss +38 -0
  54. data/scss/library/_loadify.scss +62 -0
  55. data/scss/library/_motion-safe.scss +28 -0
  56. data/scss/library/_only.scss +73 -0
  57. data/scss/library/_placeholder-shown.scss +7 -0
  58. data/scss/library/_placeholder.scss +19 -0
  59. data/scss/library/_position.scss +72 -0
  60. data/scss/library/_remove.scss +40 -0
  61. data/scss/library/_reset-css.scss +57 -0
  62. data/scss/library/_reset-figure.scss +10 -0
  63. data/scss/library/_resizable.scss +34 -0
  64. data/scss/library/_responsive-image.scss +6 -0
  65. data/scss/library/_scissors.scss +34 -0
  66. data/scss/library/_screen-agent.scss +34 -0
  67. data/scss/library/_sizer.scss +15 -0
  68. data/scss/library/_smartphone.scss +29 -0
  69. data/scss/library/_sprite.scss +100 -0
  70. data/scss/library/_stretched-link.scss +21 -0
  71. data/scss/library/_tablet.scss +29 -0
  72. data/scss/library/_text-gradient.scss +48 -0
  73. data/scss/library/_text-image.scss +15 -0
  74. data/scss/library/_text-selection.scss +22 -0
  75. data/scss/library/_text-shadow.scss +145 -0
  76. data/scss/library/_text-stroke.scss +43 -0
  77. data/scss/library/_tokens.scss +111 -0
  78. data/scss/library/_triangle.scss +115 -0
  79. data/scss/lists/_index.scss +8 -0
  80. data/scss/lists/_list-of-anchor-pseudo-classes.scss +9 -0
  81. data/scss/lists/_list-of-buttons.scss +8 -0
  82. data/scss/lists/_list-of-counter-styles.scss +59 -0
  83. data/scss/lists/_list-of-directions.scss +12 -0
  84. data/scss/lists/_list-of-length-units.scss +23 -0
  85. data/scss/lists/_list-of-text-inputs.scss +20 -0
  86. data/scss/maps/_index.scss +8 -0
  87. data/scss/maps/_map-for-breakpoints.scss +9 -0
  88. data/scss/maps/_map-for-directions.scss +12 -0
  89. data/scss/maps/_map-for-font-formats.scss +9 -0
  90. data/scss/maps/_map-for-positions.scss +13 -0
  91. data/scss/maps/_map-for-smartphones.scss +72 -0
  92. data/scss/maps/_map-for-tablets.scss +32 -0
  93. data/scss/utilities/_clear-unit.scss +11 -0
  94. data/scss/utilities/_clear-whitespace.scss +15 -0
  95. data/scss/utilities/_convert-to-em.scss +16 -0
  96. data/scss/utilities/_convert-to-number.scss +45 -0
  97. data/scss/utilities/_fill-nulls.scss +18 -0
  98. data/scss/utilities/_fluid.scss +76 -0
  99. data/scss/utilities/_font-sizer.scss +19 -0
  100. data/scss/utilities/_font-source.scss +23 -0
  101. data/scss/utilities/_gradient-value.scss +24 -0
  102. data/scss/utilities/_index.scss +26 -0
  103. data/scss/utilities/_is-color.scss +16 -0
  104. data/scss/utilities/_is-gutter.scss +24 -0
  105. data/scss/utilities/_is-number.scss +11 -0
  106. data/scss/utilities/_is-time.scss +14 -0
  107. data/scss/utilities/_map-deep-get.scss +10 -0
  108. data/scss/utilities/_pixelify.scss +20 -0
  109. data/scss/utilities/_pseudo-selector.scss +12 -0
  110. data/scss/utilities/_remify.scss +16 -0
  111. data/scss/utilities/_shade.scss +10 -0
  112. data/scss/utilities/_shorthand-property.scss +17 -0
  113. data/scss/utilities/_tint.scss +10 -0
  114. data/scss/utilities/_validate-breakpoint.scss +41 -0
  115. data/scss/utilities/_validate-length.scss +37 -0
  116. data/scss/utilities/_validate-ratio.scss +77 -0
  117. data/scss/utilities/_validate-scissors.scss +34 -0
  118. metadata +131 -46
  119. data/core/_gerillass.scss +0 -4
  120. data/core/library/_before.scss +0 -18
  121. data/core/library/_border-box.scss +0 -26
data/gerillass.json ADDED
@@ -0,0 +1,2713 @@
1
+ {
2
+ "name": "gerillass",
3
+ "version": "3.0.0",
4
+ "description": "Gerillass is an open-source toolkit that contains a set of Sass mixins to help designers and developers to create better, faster and consistent user interfaces.",
5
+ "homepage": "https://gerillass.com",
6
+ "documentation": "https://docs.gerillass.com",
7
+ "prefix": "gls-",
8
+ "load": {
9
+ "packageImporter": "@use \"pkg:gerillass\" as *;",
10
+ "bundler": "@use \"gerillass\" as *;",
11
+ "loadPath": "@use \"gerillass\" as *; // with loadPaths: [\"node_modules/gerillass/scss\"]",
12
+ "rubygems": "@use \"gerillass\" as *; // the gerillass gem: Rails and Jekyll need no setup; plain Ruby passes Gerillass.load_path"
13
+ },
14
+ "members": [
15
+ {
16
+ "name": "adaptive",
17
+ "kind": "mixin",
18
+ "arguments": [
19
+ {
20
+ "name": "$gutter",
21
+ "default": "30px",
22
+ "accepts": [
23
+ "a length subtracted from each side at every breakpoint"
24
+ ]
25
+ }
26
+ ],
27
+ "file": "scss/library/_adaptive.scss",
28
+ "signature": "adaptive($gutter: 30px)",
29
+ "summary": "Centred container whose max-width steps up at every breakpoint.",
30
+ "examples": [
31
+ ".wrap { @include adaptive; }",
32
+ ".wrap { @include adaptive(16px); }"
33
+ ],
34
+ "rejects": [
35
+ ".wrap { @include adaptive(auto); }",
36
+ ".wrap { @include adaptive(16); }",
37
+ ".wrap { @include adaptive(10deg); }",
38
+ ".wrap { @include adaptive(10px 20px); }"
39
+ ]
40
+ },
41
+ {
42
+ "name": "after",
43
+ "kind": "mixin",
44
+ "arguments": [
45
+ {
46
+ "name": "$content",
47
+ "default": "null",
48
+ "accepts": [
49
+ "a string used as the content value",
50
+ "a data- attribute name, rendered as attr()",
51
+ "null to write content yourself",
52
+ "var(), attr(), counter() or counters(), written as they are"
53
+ ]
54
+ }
55
+ ],
56
+ "file": "scss/library/_after.scss",
57
+ "signature": "after($content: null)",
58
+ "summary": "Styles the ::after pseudo-element. A `data-` argument becomes an attr() content value.",
59
+ "caveats": [
60
+ "With no argument no `content` is emitted, so the pseudo-element does not render unless the block sets `content`. Pass `\"\"` for an empty one."
61
+ ],
62
+ "examples": [
63
+ ".a { @include after(\"→\") { color: red; } }",
64
+ ".a { @include after(\"data-label\") { color: red; } }",
65
+ ".a { @include after { content: \"x\"; } }",
66
+ ".a { @include after(var(--label)) { color: red; } }",
67
+ ".a { @include after(attr(data-label)) { color: red; } }"
68
+ ],
69
+ "rejects": [
70
+ ".a { @include after(42) { color: red; } }",
71
+ ".a { @include after(16 9) { color: red; } }"
72
+ ]
73
+ },
74
+ {
75
+ "name": "all-buttons",
76
+ "kind": "mixin",
77
+ "arguments": [
78
+ {
79
+ "name": "$pseudo",
80
+ "default": "null",
81
+ "accepts": [
82
+ "hover",
83
+ "focus",
84
+ "active",
85
+ "disabled",
86
+ "null for the plain state"
87
+ ]
88
+ }
89
+ ],
90
+ "file": "scss/library/_all-buttons.scss",
91
+ "signature": "all-buttons($pseudo: null)",
92
+ "summary": "Targets every button-like element at once, optionally in one pseudo-class state.",
93
+ "examples": [
94
+ "@include all-buttons { cursor: pointer; }",
95
+ "@include all-buttons(\"hover\") { opacity: 0.8; }"
96
+ ],
97
+ "rejects": [
98
+ "@include all-buttons(nonsense) { color: red; }"
99
+ ]
100
+ },
101
+ {
102
+ "name": "all-text-inputs",
103
+ "kind": "mixin",
104
+ "arguments": [
105
+ {
106
+ "name": "$pseudo",
107
+ "default": "null",
108
+ "accepts": [
109
+ "hover",
110
+ "focus",
111
+ "active",
112
+ "invalid",
113
+ "required",
114
+ "disabled",
115
+ "focus-visible",
116
+ "user-invalid",
117
+ "null for the plain state"
118
+ ]
119
+ }
120
+ ],
121
+ "file": "scss/library/_all-text-inputs.scss",
122
+ "signature": "all-text-inputs($pseudo: null)",
123
+ "summary": "Targets every text-like input at once, optionally in one pseudo-class state.",
124
+ "examples": [
125
+ "@include all-text-inputs { border: 1px solid; }",
126
+ "@include all-text-inputs(\"focus\") { outline: 2px solid; }",
127
+ "@include all-text-inputs(\"focus-visible\") { outline: 2px solid; }",
128
+ "@include all-text-inputs(\"user-invalid\") { border-color: crimson; }"
129
+ ],
130
+ "rejects": [
131
+ "@include all-text-inputs(nonsense) { color: red; }"
132
+ ]
133
+ },
134
+ {
135
+ "name": "antialias",
136
+ "kind": "mixin",
137
+ "arguments": [
138
+ {
139
+ "name": "$value",
140
+ "default": "null",
141
+ "accepts": [
142
+ "\"only\" inside a selector to affect just that element",
143
+ "null for the element and its descendants"
144
+ ]
145
+ }
146
+ ],
147
+ "file": "scss/library/_antialias.scss",
148
+ "signature": "antialias($value: null)",
149
+ "summary": "Turns on subpixel-antialiased text smoothing.",
150
+ "examples": [
151
+ "@include antialias;",
152
+ ".a { @include antialias(\"only\"); }"
153
+ ],
154
+ "rejects": [
155
+ "@include antialias(only);",
156
+ ".a { @include antialias(bogus); }"
157
+ ]
158
+ },
159
+ {
160
+ "name": "aspect-ratio",
161
+ "kind": "mixin",
162
+ "arguments": [
163
+ {
164
+ "name": "$ratio",
165
+ "default": "null",
166
+ "accepts": [
167
+ "a slash separated string, such as \"16/9\"",
168
+ "a colon separated string, such as \"16:9\"",
169
+ "a number, where 1.5 means 1.5 / 1",
170
+ "null for the 16/9 default",
171
+ "var(), written as it is"
172
+ ]
173
+ },
174
+ {
175
+ "name": "$fit",
176
+ "default": "cover",
177
+ "accepts": [
178
+ "fill",
179
+ "contain",
180
+ "cover",
181
+ "none",
182
+ "scale-down",
183
+ "null to leave object-fit alone"
184
+ ]
185
+ }
186
+ ],
187
+ "file": "scss/library/_aspect-ratio.scss",
188
+ "signature": "aspect-ratio($ratio: null, $fit: cover)",
189
+ "summary": "Holds an element to a ratio and adds what CSS aspect-ratio alone leaves out: object-fit so an image is cropped rather than stretched, and border: 0 so an iframe does not overflow its container by 4px. Apply it to the element itself, not to a wrapper.",
190
+ "caveats": [
191
+ "On an element with a `height` attribute, such as `<img width=\"1600\" height=\"900\">` or an embed code's `<iframe>`, the attribute height wins and the ratio is ignored. Write `height: auto` after the include."
192
+ ],
193
+ "examples": [
194
+ ".thumb { @include aspect-ratio(\"16:9\"); }",
195
+ ".video { @include aspect-ratio(\"16/9\"); }",
196
+ ".tile { @include aspect-ratio(\"1:1\", contain); }",
197
+ ".plain { @include aspect-ratio(1.5, null); }",
198
+ ".default { @include aspect-ratio; }",
199
+ ".a { @include aspect-ratio(var(--ratio)); }"
200
+ ],
201
+ "rejects": [
202
+ ".thumb { @include aspect-ratio(\"16:9\", nonsense); }",
203
+ ".thumb { @include aspect-ratio(16 9); }",
204
+ ".thumb { @include aspect-ratio(\"sixteen/nine\"); }",
205
+ ".a { @include aspect-ratio(url(a.png)); }"
206
+ ]
207
+ },
208
+ {
209
+ "name": "background-dots",
210
+ "kind": "mixin",
211
+ "arguments": [
212
+ {
213
+ "name": "$color",
214
+ "default": "null",
215
+ "accepts": [
216
+ "one colour, or two for the diagonal variant, each a colour, currentColor, a system colour or a function such as var() or light-dark()",
217
+ "null for a translucent black"
218
+ ]
219
+ },
220
+ {
221
+ "name": "$size",
222
+ "default": "1em",
223
+ "accepts": [
224
+ "dot radius: a length, or var(), env() or a calculation such as calc() or clamp()"
225
+ ]
226
+ },
227
+ {
228
+ "name": "$gutter",
229
+ "default": "null",
230
+ "accepts": [
231
+ "spacing between dots, in the same forms as $size",
232
+ "null, the default, for five times $size"
233
+ ]
234
+ },
235
+ {
236
+ "name": "$diagonal",
237
+ "default": "true",
238
+ "accepts": [
239
+ "true",
240
+ "false"
241
+ ]
242
+ },
243
+ {
244
+ "name": "$image",
245
+ "default": "null",
246
+ "accepts": [
247
+ "an image path to sit behind the dots, written unquoted unless it holds a space, a parenthesis or a quote, which are quoted",
248
+ "var(), url(), image-set() or a gradient, written as they are rather than wrapped in url()"
249
+ ]
250
+ }
251
+ ],
252
+ "file": "scss/library/_background-dots.scss",
253
+ "signature": "background-dots($color: null, $size: 1em, $gutter: null, $diagonal: true, $image: null)",
254
+ "summary": "Repeating dot pattern as a background, optionally over an image.",
255
+ "examples": [
256
+ ".a { @include background-dots; }",
257
+ ".a { @include background-dots(red); }",
258
+ ".a { @include background-dots(red, 1em, 5em, false); }",
259
+ ".a { @include background-dots(red, var(--dot), calc(var(--dot) * 6)); }",
260
+ ".a { @include background-dots(red, clamp(2px, 0.5vw, 6px)); }",
261
+ ".a { @include background-dots(red, $image: var(--photo)); }"
262
+ ],
263
+ "rejects": [
264
+ ".a { @include background-dots(red, 1em, 5em, maybe); }",
265
+ ".a { @include background-dots(red, 1em, 5em, true, 42); }",
266
+ ".a { @include background-dots(red, nonsense); }",
267
+ ".a { @include background-dots(red, 1em, nonsense); }",
268
+ ".a { @include background-dots(huge); }",
269
+ ".a { @include background-dots(red 10px); }",
270
+ ".a { @include background-dots(inherit); }",
271
+ ".a { @include background-dots(red, -1em); }",
272
+ ".a { @include background-dots(red, 10deg); }",
273
+ ".a { @include background-dots(red, 2); }",
274
+ ".a { @include background-dots(red, 1em, -5em); }"
275
+ ]
276
+ },
277
+ {
278
+ "name": "background-image",
279
+ "kind": "mixin",
280
+ "arguments": [
281
+ {
282
+ "name": "$image-url",
283
+ "default": "null",
284
+ "accepts": [
285
+ "an image path, as a string; a list, a number, a colour or a boolean is refused",
286
+ "null to filter the element itself instead",
287
+ "var(), url(), image-set() or a gradient, written as they are rather than wrapped in url()"
288
+ ]
289
+ },
290
+ {
291
+ "name": "$filter-color",
292
+ "default": "null",
293
+ "accepts": [
294
+ "one colour, or several colour stops for a gradient, in the forms the gradient mixin takes",
295
+ "with $image-url null, an image as the overlay layer too: a gradient, url(), image-set() or var()",
296
+ "a word that is not a colour, a quoted colour, a length and a CSS-wide keyword are refused"
297
+ ]
298
+ },
299
+ {
300
+ "name": "$filter-direction",
301
+ "default": "null",
302
+ "accepts": [
303
+ "a direction name such as top or bottom-left",
304
+ "an angle in deg, grad, rad or turn, or 0",
305
+ "\"to top\" or \"to left top\" as a string",
306
+ "var() or calc()"
307
+ ]
308
+ }
309
+ ],
310
+ "file": "scss/library/_background-image.scss",
311
+ "signature": "background-image($image-url: null, $filter-color: null, $filter-direction: null)",
312
+ "summary": "Background image with an optional colour or gradient filter laid over it.",
313
+ "examples": [
314
+ ".a { @include background-image(\"/img/a.png\"); }",
315
+ ".a { @include background-image(\"/img/a.png\", rgba(0,0,0,0.5)); }",
316
+ ".a { @include background-image(\"/img/a.png\", (red, blue), \"top\"); }",
317
+ ".a { @include background-image(var(--hero), rgba(0,0,0,0.5)); }",
318
+ ".a { @include background-image(image-set(\"/img/a.png\" 1x, \"/img/a@2x.png\" 2x)); }"
319
+ ],
320
+ "rejects": [
321
+ ".a { @include background-image(\"/img/a.png\", (red, blue), sideways); }",
322
+ ".a { @include background-image(\"/img/a.png\", rgba(0,0,0,0.5), sideways); }",
323
+ ".a { @include background-image(null, rgba(0,0,0,0.5), sideways); }",
324
+ ".a { @include background-image(16 9); }",
325
+ ".a { @include background-image(42); }",
326
+ ".a { @include background-image(\"/img/a.png\", huge); }",
327
+ ".a { @include background-image(\"/img/a.png\", (red, 10%)); }",
328
+ ".a { @include background-image(null, 10px); }",
329
+ ".a { @include background-image(null, inherit); }",
330
+ ".a { @include background-image(\"/img/a.png\", linear-gradient(to top, black, transparent)); }"
331
+ ]
332
+ },
333
+ {
334
+ "name": "background-stripes",
335
+ "kind": "mixin",
336
+ "arguments": [
337
+ {
338
+ "name": "$color",
339
+ "default": "null",
340
+ "accepts": [
341
+ "one colour, or several for a multi-stripe pattern, each a colour, currentColor, a system colour or a function such as var() or color-mix()",
342
+ "null for a translucent black"
343
+ ]
344
+ },
345
+ {
346
+ "name": "$thickness",
347
+ "default": "1em",
348
+ "accepts": [
349
+ "stripe thickness: a length, or var(), env() or a calculation such as calc() or clamp()"
350
+ ]
351
+ },
352
+ {
353
+ "name": "$rotation",
354
+ "default": "-45deg",
355
+ "accepts": [
356
+ "an angle in deg, grad, rad or turn, in any case, written as it is",
357
+ "a unitless number, which is treated as degrees",
358
+ "any other unit, such as px or %, is refused, because the gradient would be dropped"
359
+ ]
360
+ },
361
+ {
362
+ "name": "$image",
363
+ "default": "null",
364
+ "accepts": [
365
+ "an image path to sit behind the stripes, written unquoted unless it holds a space, a parenthesis or a quote, which are quoted",
366
+ "var(), url(), image-set() or a gradient, written as they are rather than wrapped in url()"
367
+ ]
368
+ }
369
+ ],
370
+ "file": "scss/library/_background-stripes.scss",
371
+ "signature": "background-stripes($color: null, $thickness: 1em, $rotation: -45deg, $image: null)",
372
+ "summary": "Repeating stripe pattern as a background, optionally over an image.",
373
+ "examples": [
374
+ ".a { @include background-stripes; }",
375
+ ".a { @include background-stripes(red, 2em, -30deg); }",
376
+ ".a { @include background-stripes(red blue, var(--stripe)); }",
377
+ ".a { @include background-stripes(red, 2em, -30deg, var(--photo)); }"
378
+ ],
379
+ "rejects": [
380
+ ".a { @include background-stripes(red, 2em, nonsense); }",
381
+ ".a { @include background-stripes(red, 2em, -45deg, 42); }",
382
+ ".a { @include background-stripes(red, nonsense); }",
383
+ ".a { @include background-stripes(red, 2em, -10px); }",
384
+ ".a { @include background-stripes(red, 2em, 10%); }",
385
+ ".a { @include background-stripes(huge); }",
386
+ ".a { @include background-stripes(red \"blue\"); }",
387
+ ".a { @include background-stripes(red, 10deg); }",
388
+ ".a { @include background-stripes(red, 2); }"
389
+ ]
390
+ },
391
+ {
392
+ "name": "before",
393
+ "kind": "mixin",
394
+ "arguments": [
395
+ {
396
+ "name": "$content",
397
+ "default": "null",
398
+ "accepts": [
399
+ "a string used as the content value",
400
+ "a data- attribute name, rendered as attr()",
401
+ "null to write content yourself",
402
+ "var(), attr(), counter() or counters(), written as they are"
403
+ ]
404
+ }
405
+ ],
406
+ "file": "scss/library/_before.scss",
407
+ "signature": "before($content: null)",
408
+ "summary": "Styles the ::before pseudo-element. A `data-` argument becomes an attr() content value.",
409
+ "caveats": [
410
+ "With no argument no `content` is emitted, so the pseudo-element does not render unless the block sets `content`. Pass `\"\"` for an empty one."
411
+ ],
412
+ "examples": [
413
+ ".a { @include before(\"→\") { color: red; } }",
414
+ ".a { @include before(\"data-label\") { color: red; } }",
415
+ ".a { @include before(var(--label)) { color: red; } }"
416
+ ],
417
+ "rejects": [
418
+ ".a { @include before(42) { color: red; } }"
419
+ ]
420
+ },
421
+ {
422
+ "name": "border-box",
423
+ "kind": "mixin",
424
+ "arguments": [
425
+ {
426
+ "name": "$value",
427
+ "default": "null",
428
+ "accepts": [
429
+ "\"only\" inside a selector to affect just that element",
430
+ "null for the element and its descendants"
431
+ ]
432
+ }
433
+ ],
434
+ "file": "scss/library/_border-box.scss",
435
+ "signature": "border-box($value: null)",
436
+ "summary": "Applies box-sizing: border-box.",
437
+ "examples": [
438
+ "@include border-box;",
439
+ ".a { @include border-box(\"only\"); }"
440
+ ],
441
+ "rejects": [
442
+ "@include border-box(only);",
443
+ ".a { @include border-box(bogus); }"
444
+ ]
445
+ },
446
+ {
447
+ "name": "border-radius",
448
+ "kind": "mixin",
449
+ "arguments": [
450
+ {
451
+ "name": "$args",
452
+ "variadic": true,
453
+ "accepts": [
454
+ "one length for every corner",
455
+ "a corner name plus a length",
456
+ "a logical corner or edge plus a length: start-start, start-end, end-start, end-end, inline-start, inline-end, block-start or block-end",
457
+ "four lengths: top-left, top-right, bottom-right, bottom-left"
458
+ ]
459
+ }
460
+ ],
461
+ "file": "scss/library/_border-radius.scss",
462
+ "signature": "border-radius($args...)",
463
+ "summary": "Rounds corners, either all of them, one named corner, or all four individually.",
464
+ "examples": [
465
+ ".a { @include border-radius(8px); }",
466
+ ".a { @include border-radius(\"top\", 8px); }",
467
+ ".a { @include border-radius(1px, 2px, 3px, 4px); }",
468
+ ".tab { @include border-radius(\"inline-start\", 8px); }",
469
+ ".bubble { @include border-radius(\"end-end\", 12px); }"
470
+ ],
471
+ "rejects": [
472
+ ".a { @include border-radius(1px, 2px, 3px); }",
473
+ ".a { @include border-radius(nonsense, 5px); }",
474
+ ".a { @include border-radius(-4px); }",
475
+ ".a { @include border-radius(auto); }",
476
+ ".a { @include border-radius(10deg); }",
477
+ ".a { @include border-radius(1px 2px 3px 4px 5px); }",
478
+ ".a { @include border-radius(\"top\", 1px 2px 3px); }",
479
+ ".a { @include border-radius(1px, 2px, -3px, 4px); }"
480
+ ]
481
+ },
482
+ {
483
+ "name": "brand-logo",
484
+ "kind": "mixin",
485
+ "arguments": [
486
+ {
487
+ "name": "$width",
488
+ "required": true,
489
+ "accepts": [
490
+ "a length"
491
+ ]
492
+ },
493
+ {
494
+ "name": "$height",
495
+ "required": true,
496
+ "accepts": [
497
+ "a length"
498
+ ]
499
+ },
500
+ {
501
+ "name": "$image-url",
502
+ "default": "null",
503
+ "accepts": [
504
+ "an image path, as a string; a list, a number, a colour or a boolean is refused",
505
+ "var(), url(), image-set() or a gradient, written as they are rather than wrapped in url()"
506
+ ]
507
+ }
508
+ ],
509
+ "file": "scss/library/_brand-logo.scss",
510
+ "signature": "brand-logo($width, $height, $image-url: null)",
511
+ "summary": "Logo box with an image and an accessible stretched link over it.",
512
+ "examples": [
513
+ ".logo { @include brand-logo(120px, 40px, \"/img/logo.svg\"); }",
514
+ ".logo { @include brand-logo(120px, 40px, var(--logo)); }"
515
+ ],
516
+ "rejects": [
517
+ ".logo { @include brand-logo(120px, 40px, \"/img/a.svg\" \"/img/b.svg\"); }",
518
+ ".logo { @include brand-logo(120px, 40px, true); }",
519
+ ".logo { @include brand-logo(huge, 40px); }",
520
+ ".logo { @include brand-logo(120px, 10deg); }",
521
+ ".logo { @include brand-logo(\"120px\", 40px); }"
522
+ ]
523
+ },
524
+ {
525
+ "name": "breakpoint",
526
+ "kind": "mixin",
527
+ "arguments": [
528
+ {
529
+ "name": "$params",
530
+ "variadic": true,
531
+ "accepts": [
532
+ "one breakpoint name, for exactly that width, which prints a warning: write only instead",
533
+ "only plus a breakpoint, for exactly that width",
534
+ "min or max plus a breakpoint",
535
+ "between plus two breakpoints",
536
+ "a start and an end value",
537
+ "a breakpoint is a key from $map-for-breakpoints, or a length in any unit a width condition takes, 0 or a calculation; a percentage, a bare number, another unit and a word that is not a key are refused, because the query would never match"
538
+ ]
539
+ }
540
+ ],
541
+ "file": "scss/library/_breakpoint.scss",
542
+ "signature": "breakpoint($params...)",
543
+ "summary": "Media query built from the breakpoint map, or from raw lengths.",
544
+ "caveats": [
545
+ "With one argument the query matches exactly that width, `(width: 768px)`, which is a single pixel, and the mixin prints a warning. Write `only` for that width, or `min`, `max` or a range for anything wider.",
546
+ "Declarations written after the include, in the same rule, are emitted after the `@media` block and win over it. Write them before the include."
547
+ ],
548
+ "examples": [
549
+ ".a { @include breakpoint(\"only\", \"medium\") { color: red; } }",
550
+ ".a { @include breakpoint(\"min\", \"medium\") { color: red; } }",
551
+ ".a { @include breakpoint(\"between\", \"medium\" \"large\") { color: red; } }"
552
+ ],
553
+ "rejects": [
554
+ ".a { @include breakpoint(\"between\", \"medium\", \"large\") { color: red; } }",
555
+ ".a { @include breakpoint() { color: red; } }",
556
+ ".a { @include breakpoint(\"min\", var(--wide)) { color: red; } }",
557
+ ".a { @include breakpoint(\"between\", var(--start) \"large\") { color: red; } }",
558
+ ".a { @include breakpoint(\"huge\") { color: red; } }",
559
+ ".a { @include breakpoint(\"min\", \"huge\") { color: red; } }",
560
+ ".a { @include breakpoint(\"min\", \"MEDIUM\") { color: red; } }",
561
+ ".a { @include breakpoint(\"between\", \"small\" \"huge\") { color: red; } }",
562
+ ".a { @include breakpoint(\"huge\", \"large\") { color: red; } }",
563
+ ".a { @include breakpoint(\"small\", \"huge\") { color: red; } }",
564
+ ".a { @include breakpoint(\"min\", 10deg) { color: red; } }",
565
+ ".a { @include breakpoint(\"max\", 50%) { color: red; } }",
566
+ ".a { @include breakpoint(\"only\", 768) { color: red; } }"
567
+ ],
568
+ "warns": [
569
+ ".a { @include breakpoint(\"medium\") { color: red; } }"
570
+ ]
571
+ },
572
+ {
573
+ "name": "breakpointer",
574
+ "kind": "mixin",
575
+ "arguments": [
576
+ {
577
+ "name": "$selector",
578
+ "default": "null",
579
+ "accepts": [
580
+ "a selector to attach to when called at root",
581
+ "null for body"
582
+ ]
583
+ }
584
+ ],
585
+ "file": "scss/library/_breakpointer.scss",
586
+ "signature": "breakpointer($selector: null)",
587
+ "summary": "Debug helper that prints the active breakpoint name into a pseudo-element.",
588
+ "examples": [
589
+ "@include breakpointer;",
590
+ ".a { @include breakpointer; }"
591
+ ],
592
+ "rejects": [
593
+ ".a { @include breakpointer(42); }"
594
+ ]
595
+ },
596
+ {
597
+ "name": "center",
598
+ "kind": "mixin",
599
+ "arguments": [
600
+ {
601
+ "name": "$axis",
602
+ "default": "\"both\"",
603
+ "accepts": [
604
+ "both",
605
+ "horizontal",
606
+ "vertical"
607
+ ]
608
+ }
609
+ ],
610
+ "file": "scss/library/_center.scss",
611
+ "signature": "center($axis: \"both\")",
612
+ "summary": "Absolutely centres an element inside its positioned parent.",
613
+ "examples": [
614
+ ".modal { @include center; }",
615
+ ".bar { @include center(\"horizontal\"); }"
616
+ ],
617
+ "rejects": [
618
+ ".modal { @include center(diagonal); }"
619
+ ]
620
+ },
621
+ {
622
+ "name": "circle",
623
+ "kind": "mixin",
624
+ "arguments": [
625
+ {
626
+ "name": "$size",
627
+ "required": true,
628
+ "accepts": [
629
+ "a length used for both width and height"
630
+ ]
631
+ }
632
+ ],
633
+ "file": "scss/library/_circle.scss",
634
+ "signature": "circle($size)",
635
+ "summary": "Square element with a fully rounded border, i.e. a circle.",
636
+ "examples": [
637
+ ".dot { @include circle(24px); }"
638
+ ],
639
+ "rejects": [
640
+ ".dot { @include circle(huge); }",
641
+ ".dot { @include circle(24); }",
642
+ ".dot { @include circle(-24px); }"
643
+ ]
644
+ },
645
+ {
646
+ "name": "clearfix",
647
+ "kind": "mixin",
648
+ "arguments": [],
649
+ "file": "scss/library/_clearfix.scss",
650
+ "signature": "clearfix",
651
+ "summary": "Clears floated children using an ::after pseudo-element.",
652
+ "examples": [
653
+ ".row { @include clearfix; }"
654
+ ],
655
+ "rejects": []
656
+ },
657
+ {
658
+ "name": "columnizer",
659
+ "kind": "mixin",
660
+ "arguments": [
661
+ {
662
+ "name": "$params",
663
+ "variadic": true,
664
+ "accepts": [
665
+ "a column count, which may be a CSS function such as var(--cols)",
666
+ "a column count plus a gutter length, which may also be a CSS function",
667
+ "a column count plus a boolean fill flag",
668
+ "a column count, a gutter and a fill flag"
669
+ ]
670
+ }
671
+ ],
672
+ "file": "scss/library/_columnizer.scss",
673
+ "signature": "columnizer($params...)",
674
+ "summary": "Flexbox grid of equal columns, with an optional gutter and fill behaviour.",
675
+ "examples": [
676
+ ".grid { @include columnizer(3); }",
677
+ ".grid { @include columnizer(3, 20px); }",
678
+ ".grid { @include columnizer(3, 20px, true); }",
679
+ ".grid { @include columnizer(3, var(--gap)); }",
680
+ ".grid { @include columnizer(var(--cols)); }",
681
+ ".grid { @include columnizer(#{3}, 0); }"
682
+ ],
683
+ "rejects": [
684
+ ".grid { @include columnizer(3, 20px, true, 9); }",
685
+ ".grid { @include columnizer(3, nonsense); }",
686
+ ".grid { @include columnizer(3px); }",
687
+ ".grid { @include columnizer(auto); }",
688
+ ".grid { @include columnizer(3, 10deg); }",
689
+ ".grid { @include columnizer(3, 2); }",
690
+ ".grid { @include columnizer(3, red, true); }"
691
+ ]
692
+ },
693
+ {
694
+ "name": "container-query",
695
+ "kind": "mixin",
696
+ "arguments": [
697
+ {
698
+ "name": "$params",
699
+ "variadic": true,
700
+ "accepts": [
701
+ "a size, for exactly that width, which prints a warning: write only instead",
702
+ "two sizes for a range",
703
+ "one of min, max, only or between followed by a size",
704
+ "a size is a key from $map-for-breakpoints, or a length in any unit a width condition takes, 0 or a calculation; a percentage, a bare number, another unit and a word that is not a key are refused, because the query would never match",
705
+ "$name as a keyword, to query one named container"
706
+ ]
707
+ }
708
+ ],
709
+ "file": "scss/library/_container-query.scss",
710
+ "signature": "container-query($params...)",
711
+ "summary": "A @container rule, taking the same argument shapes as breakpoint so the two read alike. Sizes may be a key from $map-for-breakpoints or a raw length, and a length is the common case because a container is usually narrower than the viewport. Nothing matches at all unless an ancestor was declared with the container mixin.",
712
+ "caveats": [
713
+ "A size on its own matches exactly that width, `(width: 400px)`, which is a single pixel, and the mixin prints a warning. Write `only` for that width, or `min`, `max` or a range for anything wider."
714
+ ],
715
+ "examples": [
716
+ ".title { @include container-query(\"min\", 400px) { font-size: 2rem; } }",
717
+ ".title { @include container-query(\"max\", 399px) { font-size: 1rem; } }",
718
+ ".title { @include container-query(\"only\", 400px) { color: red; } }",
719
+ ".title { @include container-query(\"between\", 300px 500px) { color: red; } }",
720
+ ".title { @include container-query(300px, 500px) { color: red; } }",
721
+ ".title { @include container-query(\"min\", \"medium\") { color: red; } }",
722
+ ".title { @include container-query(\"min\", 400px, $name: \"card\") { color: red; } }"
723
+ ],
724
+ "rejects": [
725
+ ".title { @include container-query(\"min\", 400px, 800px) { color: red; } }",
726
+ ".title { @include container-query(\"min\", 400px, $name: 42) { color: red; } }",
727
+ ".title { @include container-query(\"min\", var(--wide)) { color: red; } }",
728
+ ".title { @include container-query(\"min\", 400px, $name: var(--container)) { color: red; } }",
729
+ ".title { @include container-query(\"min\", 400px, $name: \"none\") { color: red; } }",
730
+ ".title { @include container-query(\"min\", 400px, $name: \"not\") { color: red; } }",
731
+ ".title { @include container-query(\"min\", 400px, $name: \"my card\") { color: red; } }",
732
+ ".title { @include container-query(\"min\", 400px, $name: \"1card\") { color: red; } }",
733
+ ".title { @include container-query(\"huge\") { color: red; } }",
734
+ ".title { @include container-query(\"min\", \"huge\") { color: red; } }",
735
+ ".title { @include container-query(\"max\", 400) { color: red; } }",
736
+ ".title { @include container-query(\"between\", 300px 10deg) { color: red; } }",
737
+ ".title { @include container-query(300px, 50%) { color: red; } }"
738
+ ],
739
+ "warns": [
740
+ ".title { @include container-query(400px) { color: red; } }"
741
+ ]
742
+ },
743
+ {
744
+ "name": "container",
745
+ "kind": "mixin",
746
+ "arguments": [
747
+ {
748
+ "name": "$name",
749
+ "default": "null",
750
+ "accepts": [
751
+ "a container name as a string, such as \"card\"",
752
+ "null for an unnamed container"
753
+ ]
754
+ },
755
+ {
756
+ "name": "$type",
757
+ "default": "inline-size",
758
+ "accepts": [
759
+ "inline-size",
760
+ "size",
761
+ "normal"
762
+ ]
763
+ }
764
+ ],
765
+ "file": "scss/library/_container.scss",
766
+ "signature": "container($name: null, $type: inline-size)",
767
+ "summary": "Marks an element as a query container, so container-query can ask about its width instead of the viewport's. The rule that asks has to sit on a descendant: an element is never matched by a @container rule reading its own container, and nothing warns you when it is not.",
768
+ "caveats": [
769
+ "An element does not match a `@container` query that reads its own container, and nothing warns. Put the `container-query` on a descendant."
770
+ ],
771
+ "examples": [
772
+ ".card { @include container(\"card\"); }",
773
+ ".panel { @include container; }",
774
+ ".panel { @include container(null, size); }"
775
+ ],
776
+ "rejects": [
777
+ ".card { @include container(\"card\", sideways); }",
778
+ ".card { @include container(42); }",
779
+ ".card { @include container(\"and\"); }",
780
+ ".card { @include container(\"1card\"); }"
781
+ ]
782
+ },
783
+ {
784
+ "name": "counter",
785
+ "kind": "mixin",
786
+ "arguments": [
787
+ {
788
+ "name": "$params",
789
+ "variadic": true,
790
+ "accepts": [
791
+ "a counter style name",
792
+ "a prefix and/or suffix string",
793
+ "a prefix, a counter style and a suffix",
794
+ "var(), attr(), counter() or counters() in place of a prefix or suffix, written as they are"
795
+ ]
796
+ }
797
+ ],
798
+ "file": "scss/library/_counter.scss",
799
+ "signature": "counter($params...)",
800
+ "summary": "CSS counter for a list, with optional text before and after the number.",
801
+ "caveats": [
802
+ "Numbering restarts on every item, each showing the first number, when the items are size containers (`container-type: inline-size`): containment scopes counters to each item."
803
+ ],
804
+ "examples": [
805
+ ".list { @include counter(\"decimal\"); }",
806
+ ".list { @include counter(\".\"); }",
807
+ ".list { @include counter(\"(\", \"decimal\", \")\"); }",
808
+ ".list { @include counter(var(--prefix), \"decimal\"); }"
809
+ ],
810
+ "rejects": []
811
+ },
812
+ {
813
+ "name": "ellipsis",
814
+ "kind": "mixin",
815
+ "arguments": [
816
+ {
817
+ "name": "$width",
818
+ "default": "100%",
819
+ "accepts": [
820
+ "a max-width"
821
+ ]
822
+ },
823
+ {
824
+ "name": "$display",
825
+ "default": "inline-block",
826
+ "accepts": [
827
+ "a display keyword, or two or three in any order naming at most one outer type, one inner type and list-item, such as inline flex",
828
+ "a vendor keyword such as -webkit-box, a CSS-wide keyword, or var()",
829
+ "null to leave display out",
830
+ "a quoted value is written without its quotes; a combination the browser drops, such as block inline, is refused"
831
+ ]
832
+ }
833
+ ],
834
+ "file": "scss/library/_ellipsis.scss",
835
+ "signature": "ellipsis($width: 100%, $display: inline-block)",
836
+ "summary": "Truncates a single line of text with an ellipsis.",
837
+ "examples": [
838
+ ".a { @include ellipsis; }",
839
+ ".a { @include ellipsis(200px); }"
840
+ ],
841
+ "rejects": [
842
+ ".a { @include ellipsis(100%, huge); }",
843
+ ".a { @include ellipsis(100%, block inline); }",
844
+ ".a { @include ellipsis(100%, inline-block flow); }",
845
+ ".a { @include ellipsis(100%, 10px); }",
846
+ ".a { @include ellipsis(huge); }",
847
+ ".a { @include ellipsis(auto); }",
848
+ ".a { @include ellipsis(-10px); }",
849
+ ".a { @include ellipsis(200); }"
850
+ ]
851
+ },
852
+ {
853
+ "name": "escape-to-parent",
854
+ "kind": "mixin",
855
+ "arguments": [
856
+ {
857
+ "name": "$selector",
858
+ "default": "null",
859
+ "accepts": [
860
+ "a selector to prepend"
861
+ ]
862
+ }
863
+ ],
864
+ "file": "scss/library/_escape-to-parent.scss",
865
+ "signature": "escape-to-parent($selector: null)",
866
+ "summary": "Re-roots the current selector under another one using @at-root.",
867
+ "examples": [
868
+ ".a { @include escape-to-parent(\".theme-dark\") { color: white; } }"
869
+ ],
870
+ "rejects": [
871
+ ".a { @include escape-to-parent(42) { color: red; } }"
872
+ ]
873
+ },
874
+ {
875
+ "name": "except",
876
+ "kind": "mixin",
877
+ "arguments": [
878
+ {
879
+ "name": "$params",
880
+ "variadic": true,
881
+ "accepts": [
882
+ "a positive or negative index, a whole number other than 0; a unit or a fraction makes a selector the browser drops, and 0 excludes nothing, so both are refused",
883
+ "a multiple of n such as 3n, to exclude every third element; an offset such as 2n+1 is computed by Sass first and arrives as 3n",
884
+ "first, last, odd or even",
885
+ "a selector such as .foo",
886
+ "several indexes, all of them numbers"
887
+ ]
888
+ }
889
+ ],
890
+ "file": "scss/library/_except.scss",
891
+ "signature": "except($params...)",
892
+ "summary": "Selects every sibling except the ones named.",
893
+ "caveats": [
894
+ "An+B with an offset cannot be passed as a number: Sass does the arithmetic, so `except(2n+1)` becomes `3n` and excludes every third element, not the odd ones. Use `odd` or `even`, or a coefficient alone such as `3n`."
895
+ ],
896
+ "examples": [
897
+ ".a { @include except(\"first\") { margin: 0; } }",
898
+ ".a { @include except(2) { margin: 0; } }",
899
+ ".a { @include except(1, 3) { margin: 0; } }",
900
+ ".a { @include except(3n) { margin: 0; } }"
901
+ ],
902
+ "rejects": [
903
+ ".a { @include except(#ff0000) { margin: 0; } }",
904
+ ".a { @include except(10deg) { margin: 0; } }",
905
+ ".a { @include except(-10px) { margin: 0; } }",
906
+ ".a { @include except(1.5) { margin: 0; } }",
907
+ ".a { @include except(0) { margin: 0; } }",
908
+ ".a { @include except(0n) { margin: 0; } }",
909
+ ".a { @include except(1, 10deg) { margin: 0; } }",
910
+ ".a { @include except(2, \"first\") { margin: 0; } }"
911
+ ]
912
+ },
913
+ {
914
+ "name": "focus-ring",
915
+ "kind": "mixin",
916
+ "arguments": [
917
+ {
918
+ "name": "$width",
919
+ "default": "2px",
920
+ "accepts": [
921
+ "an outline width, such as 2px"
922
+ ]
923
+ },
924
+ {
925
+ "name": "$offset",
926
+ "default": "2px",
927
+ "accepts": [
928
+ "a length; negative draws the ring inside the element"
929
+ ]
930
+ },
931
+ {
932
+ "name": "$color",
933
+ "default": "currentColor",
934
+ "accepts": [
935
+ "a colour, currentColor, a system colour such as Highlight, or a function such as var() or color-mix()",
936
+ "a word that is not a colour, a quoted colour, a length and a CSS-wide keyword are refused, because the outline would be dropped"
937
+ ]
938
+ }
939
+ ],
940
+ "file": "scss/library/_focus-ring.scss",
941
+ "signature": "focus-ring($width: 2px, $offset: 2px, $color: currentColor)",
942
+ "summary": "Draws a keyboard focus ring with outline on :focus-visible, which survives forced-colors mode where a box-shadow ring disappears.",
943
+ "examples": [
944
+ ".button { @include focus-ring; }",
945
+ ".card-link { @include focus-ring(3px, 4px, var(--focus)); }"
946
+ ],
947
+ "rejects": [
948
+ "@include focus-ring;",
949
+ ".button { @include focus-ring(2px, 2px, huge); }",
950
+ ".button { @include focus-ring(2px, 2px, \"red\"); }",
951
+ ".button { @include focus-ring(2px, 2px, 10px); }",
952
+ ".button { @include focus-ring(2px, 2px, inherit); }",
953
+ ".button { @include focus-ring(huge); }",
954
+ ".button { @include focus-ring(5%); }",
955
+ ".button { @include focus-ring(-2px); }",
956
+ ".button { @include focus-ring(2px, 5%); }",
957
+ ".button { @include focus-ring(2px, thin); }"
958
+ ]
959
+ },
960
+ {
961
+ "name": "font-face",
962
+ "kind": "mixin",
963
+ "arguments": [
964
+ {
965
+ "name": "$font-family",
966
+ "required": true,
967
+ "accepts": [
968
+ "the family name"
969
+ ]
970
+ },
971
+ {
972
+ "name": "$file-path",
973
+ "required": true,
974
+ "accepts": [
975
+ "path to the files, without an extension"
976
+ ]
977
+ },
978
+ {
979
+ "name": "$font-style",
980
+ "default": "normal",
981
+ "accepts": [
982
+ "normal, italic, oblique or auto, or oblique with one or two angles from -90deg to 90deg",
983
+ "a number from 1 to 1000, which is read as the weight"
984
+ ]
985
+ },
986
+ {
987
+ "name": "$font-weight",
988
+ "default": "400",
989
+ "accepts": [
990
+ "normal, bold, auto, or a number from 1 to 1000",
991
+ "two numbers for a variable font's range, such as 100 900",
992
+ "bolder, lighter and the CSS-wide keywords are refused, because a @font-face rule drops them"
993
+ ]
994
+ },
995
+ {
996
+ "name": "$file-formats",
997
+ "default": "eot woff2 woff ttf svg",
998
+ "accepts": [
999
+ "any of eot, woff2, woff, ttf, svg"
1000
+ ]
1001
+ },
1002
+ {
1003
+ "name": "$font-display",
1004
+ "default": "null",
1005
+ "accepts": [
1006
+ "auto, block, swap, fallback or optional",
1007
+ "null, the default, to leave font-display out"
1008
+ ]
1009
+ }
1010
+ ],
1011
+ "file": "scss/library/_font-face.scss",
1012
+ "signature": "font-face($font-family, $file-path, $font-style: normal, $font-weight: 400, $file-formats: eot woff2 woff ttf svg, $font-display: null)",
1013
+ "summary": "Emits an @font-face rule for one family across several file formats. Must be called at the root.",
1014
+ "examples": [
1015
+ "@include font-face(\"Inter\", \"/fonts/inter\");",
1016
+ "@include font-face(\"Inter\", \"/fonts/inter\", italic, 700, woff2 woff);",
1017
+ "@include font-face(\"Readex Pro\", \"/fonts/readex\", $font-weight: 160 700, $file-formats: woff2, $font-display: swap);",
1018
+ "@include font-face(\"Inter\", \"/fonts/inter\", \"italic\", $font-weight: \"bold\", $file-formats: woff2);",
1019
+ "@include font-face(\"Inter\", \"/fonts/inter\", oblique 10deg 20deg, $font-weight: 450.5, $file-formats: woff2);",
1020
+ "@include font-face(\"Inter\", \"/fonts/inter\", auto, \"100 900\", $file-formats: woff2);"
1021
+ ],
1022
+ "rejects": [
1023
+ ".a { @include font-face(\"Inter\", \"/fonts/inter\"); }",
1024
+ "@include font-face(42, \"/fonts/x\");",
1025
+ "@include font-face(\"Inter\", 42);",
1026
+ "@include font-face(\"Inter\", \"/fonts/inter\", $file-formats: otf);",
1027
+ "@include font-face(\"Inter\", \"/fonts/inter\", $file-formats: woff2 wof);",
1028
+ "@include font-face(\"Inter\", \"/fonts/inter\", $file-formats: null);",
1029
+ "@include font-face(\"Inter\", var(--font-path));",
1030
+ "@include font-face(\"Inter\", \"/fonts/inter\", $file-formats: woff2, $font-display: fast);",
1031
+ "@include font-face(\"Inter\", \"/fonts/inter\", $file-formats: woff2, $font-display: var(--display));",
1032
+ "@include font-face(var(--font-family), \"/fonts/inter\", $file-formats: woff2);",
1033
+ "@include font-face(\"Inter\", \"/fonts/inter\", var(--font-style), $file-formats: woff2);",
1034
+ "@include font-face(\"Inter\", \"/fonts/inter\", $font-weight: var(--font-weight), $file-formats: woff2);",
1035
+ "@include font-face(\"Inter\", \"/fonts/inter\", $font-weight: 100 var(--max-weight), $file-formats: woff2);",
1036
+ "@include font-face(sans-serif, \"/fonts/inter\", $file-formats: woff2);",
1037
+ "@include font-face(inherit, \"/fonts/inter\", $file-formats: woff2);",
1038
+ "@include font-face(env(--font-family), \"/fonts/inter\", $file-formats: woff2);",
1039
+ "@include font-face(\"Inter\", \"/fonts/inter\", huge, $file-formats: woff2);",
1040
+ "@include font-face(\"Inter\", \"/fonts/inter\", oblique 100deg, $file-formats: woff2);",
1041
+ "@include font-face(\"Inter\", \"/fonts/inter\", inherit, $file-formats: woff2);",
1042
+ "@include font-face(\"Inter\", \"/fonts/inter\", $font-weight: huge, $file-formats: woff2);",
1043
+ "@include font-face(\"Inter\", \"/fonts/inter\", $font-weight: bolder, $file-formats: woff2);",
1044
+ "@include font-face(\"Inter\", \"/fonts/inter\", $font-weight: 0, $file-formats: woff2);",
1045
+ "@include font-face(\"Inter\", \"/fonts/inter\", $font-weight: 100 200 300, $file-formats: woff2);"
1046
+ ]
1047
+ },
1048
+ {
1049
+ "name": "gradient",
1050
+ "kind": "mixin",
1051
+ "arguments": [
1052
+ {
1053
+ "name": "$colors",
1054
+ "required": true,
1055
+ "accepts": [
1056
+ "one or more colour stops: a colour, or a colour with one or two positions, such as (red 0 10%) (blue 10% 100%)",
1057
+ "a position on its own between two colours, as a hint",
1058
+ "for a conic gradient the positions are angles or percentages, not lengths",
1059
+ "var() for a stop or the whole list",
1060
+ "a single colour warns, because browsers before Chrome 135, Firefox 136 and Safari 18.4 drop that gradient"
1061
+ ]
1062
+ },
1063
+ {
1064
+ "name": "$type",
1065
+ "default": "linear",
1066
+ "accepts": [
1067
+ "linear, the default",
1068
+ "radial",
1069
+ "conic"
1070
+ ]
1071
+ },
1072
+ {
1073
+ "name": "$direction",
1074
+ "default": "null",
1075
+ "accepts": [
1076
+ "linear only",
1077
+ "a direction name such as top or bottom-left",
1078
+ "an angle in deg, grad, rad or turn, or 0",
1079
+ "\"to top\" or \"to left top\" as a string",
1080
+ "var() or calc()"
1081
+ ]
1082
+ },
1083
+ {
1084
+ "name": "$shape",
1085
+ "default": "null",
1086
+ "accepts": [
1087
+ "radial only",
1088
+ "circle or ellipse, with an optional size as a string, such as \"circle 10px\""
1089
+ ]
1090
+ },
1091
+ {
1092
+ "name": "$position",
1093
+ "default": "null",
1094
+ "accepts": [
1095
+ "radial or conic",
1096
+ "a position name such as center or top-left",
1097
+ "at followed by a position, as a string, such as \"at 30% 40%\"; a radial gradient may put a size before it"
1098
+ ]
1099
+ },
1100
+ {
1101
+ "name": "$from",
1102
+ "default": "null",
1103
+ "accepts": [
1104
+ "conic only",
1105
+ "an angle in deg, grad, rad or turn, 0, or var()"
1106
+ ]
1107
+ },
1108
+ {
1109
+ "name": "$in",
1110
+ "default": "null",
1111
+ "accepts": [
1112
+ "a colour space: srgb, srgb-linear, display-p3, display-p3-linear, a98-rgb, prophoto-rgb, rec2020, lab, oklab, xyz, xyz-d50 or xyz-d65",
1113
+ "a polar space, hsl, hwb, lch or oklch, with an optional hue method as a string, such as \"oklch longer hue\"",
1114
+ "var()",
1115
+ "the gradient is written once without the space first, for a browser that does not know it"
1116
+ ]
1117
+ },
1118
+ {
1119
+ "name": "$repeating",
1120
+ "default": "false",
1121
+ "accepts": [
1122
+ "false, the default",
1123
+ "true, for a repeating gradient"
1124
+ ]
1125
+ }
1126
+ ],
1127
+ "file": "scss/library/_gradient.scss",
1128
+ "signature": "gradient($colors, $type: linear, $direction: null, $shape: null, $position: null, $from: null, $in: null, $repeating: false)",
1129
+ "summary": "A linear, radial or conic gradient as background-image, plain or repeating, with an optional colour interpolation space. Replaced linear-gradient and radial-gradient in 3.0.0.",
1130
+ "examples": [
1131
+ ".a { @include gradient((red, blue)); }",
1132
+ ".a { @include gradient((red, blue), $direction: \"top-right\"); }",
1133
+ ".a { @include gradient((red, blue), radial, $shape: circle, $position: \"top-left\"); }",
1134
+ ".a { @include gradient((teal 0 40%, purple 40% 75%, coral 75% 100%), conic); }",
1135
+ ".a { @include gradient((black 0 25%, white 0 50%), conic, $repeating: true); }",
1136
+ ".a { @include gradient((blue, yellow), $direction: right, $in: oklab); }"
1137
+ ],
1138
+ "rejects": [
1139
+ ".a { @include gradient((red, blue), sideways); }",
1140
+ ".a { @include gradient((red, blue), $direction: 10px); }",
1141
+ ".a { @include gradient((red, blue), $direction: \"to center\"); }",
1142
+ ".a { @include gradient((red, blue), radial, $direction: top); }",
1143
+ ".a { @include gradient((red, blue), $shape: circle); }",
1144
+ ".a { @include gradient((red, blue), $position: center); }",
1145
+ ".a { @include gradient((red, blue), $from: 45deg); }",
1146
+ ".a { @include gradient((red, blue), conic, $from: 10px); }",
1147
+ ".a { @include gradient((red, blue), conic, $position: \"closest-side at center\"); }",
1148
+ ".a { @include gradient((red 10px, blue), conic); }",
1149
+ ".a { @include gradient((red, blue), radial, $shape: \"circle 10%\"); }",
1150
+ ".a { @include gradient((huge, blue)); }",
1151
+ ".a { @include gradient((red, blue), $in: rgb); }",
1152
+ ".a { @include gradient((red, blue), $in: \"oklab longer hue\"); }",
1153
+ ".a { @include gradient((red, blue), $repeating: yes); }"
1154
+ ],
1155
+ "warns": [
1156
+ ".a { @include gradient(red); }"
1157
+ ]
1158
+ },
1159
+ {
1160
+ "name": "hide",
1161
+ "kind": "mixin",
1162
+ "arguments": [
1163
+ {
1164
+ "name": "$toggle",
1165
+ "default": "\"hide\"",
1166
+ "accepts": [
1167
+ "hide",
1168
+ "unhide"
1169
+ ]
1170
+ }
1171
+ ],
1172
+ "file": "scss/library/_hide.scss",
1173
+ "signature": "hide($toggle: \"hide\")",
1174
+ "summary": "Visually hides an element while keeping it available to screen readers, or reverses that.",
1175
+ "examples": [
1176
+ ".a { @include hide; }",
1177
+ ".a { @include hide(\"unhide\"); }"
1178
+ ],
1179
+ "rejects": [
1180
+ ".a { @include hide(nonsense); }"
1181
+ ]
1182
+ },
1183
+ {
1184
+ "name": "line-clamp",
1185
+ "kind": "mixin",
1186
+ "arguments": [
1187
+ {
1188
+ "name": "$lines",
1189
+ "default": "3",
1190
+ "accepts": [
1191
+ "a whole number of lines, at least 1",
1192
+ "none, to undo a clamp",
1193
+ "var(), written as it is"
1194
+ ]
1195
+ }
1196
+ ],
1197
+ "file": "scss/library/_line-clamp.scss",
1198
+ "signature": "line-clamp($lines: 3)",
1199
+ "summary": "Truncates text after a number of lines, where ellipsis truncates one. It emits five declarations rather than one because -webkit-line-clamp does nothing on its own: without display: -webkit-box or without -webkit-box-orient: vertical the text is not clamped at all and nothing warns you, and without overflow: hidden the clamped text spills out below the box. The unprefixed line-clamp is emitted too, for when it becomes Baseline.",
1200
+ "examples": [
1201
+ ".excerpt { @include line-clamp(3); }",
1202
+ ".title { @include line-clamp(2); }",
1203
+ ".full { @include line-clamp(none); }",
1204
+ ".default { @include line-clamp; }",
1205
+ ".a { @include line-clamp(var(--lines)); }"
1206
+ ],
1207
+ "rejects": [
1208
+ ".a { @include line-clamp(0); }",
1209
+ ".a { @include line-clamp(2.5); }",
1210
+ ".a { @include line-clamp(3px); }",
1211
+ ".a { @include line-clamp(\"three\"); }",
1212
+ ".a { @include line-clamp(url(a.png)); }"
1213
+ ]
1214
+ },
1215
+ {
1216
+ "name": "loadify",
1217
+ "kind": "mixin",
1218
+ "arguments": [
1219
+ {
1220
+ "name": "$params",
1221
+ "variadic": true,
1222
+ "accepts": [
1223
+ "init at the root, or nothing",
1224
+ "a delay, and optionally a duration, on an element"
1225
+ ]
1226
+ }
1227
+ ],
1228
+ "file": "scss/library/_loadify.scss",
1229
+ "signature": "loadify($params...)",
1230
+ "summary": "Fades elements in on page load. Call once at the root to set up, then on each element. Under prefers-reduced-motion: reduce the end state is applied directly and no animation runs. Switching the animation off alone would not do, because the element starts invisible and the animation is what reveals it, so the content would stay hidden for good.",
1231
+ "caveats": [
1232
+ "`init` and every call must be in the same module, or the module with the call must `@use` the one that calls `init`. Otherwise Sass fails with \"The target selector was not found\"."
1233
+ ],
1234
+ "examples": [
1235
+ "@include loadify(init);\n.a { @include loadify; }",
1236
+ "@include loadify;\n.a { @include loadify(0.4s, 1s); }"
1237
+ ],
1238
+ "rejects": [
1239
+ "@include loadify(nonsense);"
1240
+ ]
1241
+ },
1242
+ {
1243
+ "name": "motion-safe",
1244
+ "kind": "mixin",
1245
+ "arguments": [],
1246
+ "file": "scss/library/_motion-safe.scss",
1247
+ "signature": "motion-safe",
1248
+ "summary": "Wraps its content in @media (prefers-reduced-motion: no-preference), so motion is opt-in: a user who asked their system for less motion gets none of it.",
1249
+ "caveats": [
1250
+ "Keep the resting state outside the block. An element hidden in its base rule and revealed by an animation inside the block stays hidden for a user who asked for less motion; put the start state in the keyframes instead."
1251
+ ],
1252
+ "examples": [
1253
+ ".card { @include motion-safe { transition: transform 0.2s ease; } }",
1254
+ "@include motion-safe { .spinner { animation: spin 1s linear infinite; } }"
1255
+ ],
1256
+ "rejects": [
1257
+ ".card { @include motion-safe; }"
1258
+ ]
1259
+ },
1260
+ {
1261
+ "name": "only",
1262
+ "kind": "mixin",
1263
+ "arguments": [
1264
+ {
1265
+ "name": "$params",
1266
+ "variadic": true,
1267
+ "accepts": [
1268
+ "a positive or negative index, a whole number other than 0; a unit or a fraction makes a selector the browser drops, and 0 matches nothing, so both are refused",
1269
+ "a multiple of n such as 3n, for every third element; an offset such as 2n+1 is computed by Sass first and arrives as 3n",
1270
+ "first, last, odd or even",
1271
+ "a selector such as .foo",
1272
+ "several indexes, all of them numbers"
1273
+ ]
1274
+ }
1275
+ ],
1276
+ "file": "scss/library/_only.scss",
1277
+ "signature": "only($params...)",
1278
+ "summary": "Selects only the siblings named.",
1279
+ "caveats": [
1280
+ "An+B with an offset cannot be passed as a number: Sass does the arithmetic, so `only(2n+1)` becomes `3n` and selects every third element, not the odd ones. Use `odd` or `even`, or a coefficient alone such as `3n`."
1281
+ ],
1282
+ "examples": [
1283
+ ".a { @include only(\"first\") { margin: 0; } }",
1284
+ ".a { @include only(-1) { margin: 0; } }",
1285
+ ".a { @include only(1, 3) { margin: 0; } }",
1286
+ ".a { @include only(3n) { margin: 0; } }"
1287
+ ],
1288
+ "rejects": [
1289
+ ".a { @include only(#ff0000) { margin: 0; } }",
1290
+ ".a { @include only(10deg) { margin: 0; } }",
1291
+ ".a { @include only(-10px) { margin: 0; } }",
1292
+ ".a { @include only(1.5) { margin: 0; } }",
1293
+ ".a { @include only(0) { margin: 0; } }",
1294
+ ".a { @include only(0n) { margin: 0; } }",
1295
+ ".a { @include only(1, 10deg) { margin: 0; } }",
1296
+ ".a { @include only(2, \"first\") { margin: 0; } }"
1297
+ ]
1298
+ },
1299
+ {
1300
+ "name": "placeholder-shown",
1301
+ "kind": "mixin",
1302
+ "arguments": [],
1303
+ "file": "scss/library/_placeholder-shown.scss",
1304
+ "signature": "placeholder-shown",
1305
+ "summary": "Styles an input while its placeholder is visible.",
1306
+ "examples": [
1307
+ ".field { @include placeholder-shown { border-color: gray; } }"
1308
+ ],
1309
+ "rejects": []
1310
+ },
1311
+ {
1312
+ "name": "placeholder",
1313
+ "kind": "mixin",
1314
+ "arguments": [],
1315
+ "file": "scss/library/_placeholder.scss",
1316
+ "signature": "placeholder",
1317
+ "summary": "Styles the placeholder text of an input across vendor prefixes.",
1318
+ "examples": [
1319
+ ".field { @include placeholder { color: gray; } }"
1320
+ ],
1321
+ "rejects": []
1322
+ },
1323
+ {
1324
+ "name": "position",
1325
+ "kind": "mixin",
1326
+ "arguments": [
1327
+ {
1328
+ "name": "$position",
1329
+ "default": "absolute",
1330
+ "accepts": [
1331
+ "static, relative, absolute, fixed or sticky, in any case, or a vendor keyword such as -webkit-sticky",
1332
+ "a CSS-wide keyword or var()",
1333
+ "null to leave position out",
1334
+ "a quoted keyword is written without its quotes; any other word is refused, because the declaration would be dropped"
1335
+ ]
1336
+ },
1337
+ {
1338
+ "name": "$offsets",
1339
+ "default": "0",
1340
+ "accepts": [
1341
+ "one to four lengths in shorthand order, or auto/inherit/initial/0",
1342
+ "null in any position to leave that edge out"
1343
+ ]
1344
+ },
1345
+ {
1346
+ "name": "$logical",
1347
+ "default": "false",
1348
+ "accepts": [
1349
+ "false, the default, for top, right, bottom and left",
1350
+ "null, read as false",
1351
+ "true for inset-block-start, inset-inline-end, inset-block-end and inset-inline-start, which follow the writing direction"
1352
+ ]
1353
+ }
1354
+ ],
1355
+ "file": "scss/library/_position.scss",
1356
+ "signature": "position($position: absolute, $offsets: 0, $logical: false)",
1357
+ "summary": "Sets position and offsets in one call, using shorthand order.",
1358
+ "examples": [
1359
+ ".a { @include position(absolute, 0); }",
1360
+ ".a { @include position(fixed, 0 10px); }",
1361
+ ".a { @include position(absolute, null 16px 16px 16px); }",
1362
+ ".a { @include position(absolute, 0 null null 0); }",
1363
+ ".badge { @include position(absolute, 0 auto auto 1rem, $logical: true); }",
1364
+ ".a { @include position(absolute, 0, $logical: null); }",
1365
+ ".a { @include position(absolute, #{16}px AUTO revert-layer); }",
1366
+ ".tip { @include position(absolute, anchor(bottom) null null anchor(left)); }"
1367
+ ],
1368
+ "rejects": [
1369
+ ".badge { @include position(absolute, 0, $logical: yes); }",
1370
+ ".a { @include position(huge, 0); }",
1371
+ ".a { @include position(10px, 0); }",
1372
+ ".a { @include position(\"absolute fixed\", 0); }",
1373
+ ".a { @include position(absolute, 5); }",
1374
+ ".a { @include position(absolute, 0 10deg); }",
1375
+ ".a { @include position(absolute, none); }",
1376
+ ".a { @include position(absolute, red); }",
1377
+ ".a { @include position(absolute, \"10px\"); }",
1378
+ ".a { @include position(absolute, url(a.png)); }"
1379
+ ]
1380
+ },
1381
+ {
1382
+ "name": "remove",
1383
+ "kind": "mixin",
1384
+ "arguments": [
1385
+ {
1386
+ "name": "$params",
1387
+ "variadic": true,
1388
+ "accepts": [
1389
+ "nothing, to hide it always",
1390
+ "one breakpoint, for exactly that width and no other, which prints a warning: write only instead",
1391
+ "only plus a breakpoint, for exactly that width",
1392
+ "min or max plus a breakpoint",
1393
+ "a start and an end breakpoint"
1394
+ ]
1395
+ }
1396
+ ],
1397
+ "file": "scss/library/_remove.scss",
1398
+ "signature": "remove($params...)",
1399
+ "summary": "Hides an element outright, or within a media query: from a breakpoint up with min, up to it with max, or between two breakpoints. One breakpoint on its own hides the element at exactly that width, a single pixel, and prints a warning: pass only for that.",
1400
+ "caveats": [
1401
+ "With one argument the element is hidden at exactly that width, `(width: 768px)`, which is a single pixel, and the mixin prints a warning. Write `only` for that width, or `min`, `max` or a range for anything wider.",
1402
+ "A `display` written after the include, in the same rule, is emitted after the `@media` block and wins over it. Write it before the include."
1403
+ ],
1404
+ "examples": [
1405
+ ".a { @include remove; }",
1406
+ ".a { @include remove(\"min\", \"medium\"); }",
1407
+ ".a { @include remove(\"max\", \"medium\"); }",
1408
+ ".a { @include remove(\"only\", \"medium\"); }",
1409
+ ".a { @include remove(\"small\", \"large\"); }"
1410
+ ],
1411
+ "rejects": [
1412
+ ".a { @include remove(a, b, c); }",
1413
+ ".a { @include remove(\"max\", var(--narrow)); }",
1414
+ ".a { @include remove(\"huge\"); }",
1415
+ ".a { @include remove(\"min\", \"huge\"); }",
1416
+ ".a { @include remove(\"huge\", \"large\"); }"
1417
+ ],
1418
+ "warns": [
1419
+ ".a { @include remove(\"medium\"); }"
1420
+ ]
1421
+ },
1422
+ {
1423
+ "name": "reset-css",
1424
+ "kind": "mixin",
1425
+ "arguments": [],
1426
+ "file": "scss/library/_reset-css.scss",
1427
+ "signature": "reset-css",
1428
+ "summary": "Meyer reset. Must be called at the root of the stylesheet.",
1429
+ "examples": [
1430
+ "@include reset-css;"
1431
+ ],
1432
+ "rejects": [
1433
+ ".a { @include reset-css; }"
1434
+ ]
1435
+ },
1436
+ {
1437
+ "name": "reset-figure",
1438
+ "kind": "mixin",
1439
+ "arguments": [],
1440
+ "file": "scss/library/_reset-figure.scss",
1441
+ "signature": "reset-figure",
1442
+ "summary": "Removes default figure margins and makes the image inside responsive.",
1443
+ "examples": [
1444
+ "figure { @include reset-figure; }"
1445
+ ],
1446
+ "rejects": []
1447
+ },
1448
+ {
1449
+ "name": "resizable",
1450
+ "kind": "mixin",
1451
+ "arguments": [
1452
+ {
1453
+ "name": "$direction",
1454
+ "default": "both",
1455
+ "accepts": [
1456
+ "none, both, horizontal, vertical, block, inline or auto, in any case",
1457
+ "a CSS-wide keyword, var(), or null to leave resize out; a quoted keyword is written without its quotes"
1458
+ ]
1459
+ },
1460
+ {
1461
+ "name": "$overflow",
1462
+ "default": "auto",
1463
+ "accepts": [
1464
+ "one or two of visible, hidden, clip, scroll, auto and overlay, such as hidden auto",
1465
+ "a CSS-wide keyword on its own, var(), or null to leave overflow out; a quoted value is written without its quotes"
1466
+ ]
1467
+ }
1468
+ ],
1469
+ "file": "scss/library/_resizable.scss",
1470
+ "signature": "resizable($direction: both, $overflow: auto)",
1471
+ "summary": "Makes an element user-resizable.",
1472
+ "examples": [
1473
+ ".a { @include resizable; }",
1474
+ ".a { @include resizable(vertical, scroll); }"
1475
+ ],
1476
+ "rejects": [
1477
+ ".a { @include resizable(huge); }",
1478
+ ".a { @include resizable(both, huge); }",
1479
+ ".a { @include resizable(both, hidden hidden hidden); }",
1480
+ ".a { @include resizable(both, inherit auto); }"
1481
+ ]
1482
+ },
1483
+ {
1484
+ "name": "responsive-image",
1485
+ "kind": "mixin",
1486
+ "arguments": [],
1487
+ "file": "scss/library/_responsive-image.scss",
1488
+ "signature": "responsive-image",
1489
+ "summary": "Makes an image fill its container width.",
1490
+ "examples": [
1491
+ "img { @include responsive-image; }"
1492
+ ],
1493
+ "rejects": []
1494
+ },
1495
+ {
1496
+ "name": "scissors",
1497
+ "kind": "mixin",
1498
+ "arguments": [
1499
+ {
1500
+ "name": "$corners",
1501
+ "required": true,
1502
+ "accepts": [
1503
+ "one length for every corner",
1504
+ "four lengths: top-left, top-right, bottom-right, bottom-left"
1505
+ ]
1506
+ }
1507
+ ],
1508
+ "file": "scss/library/_scissors.scss",
1509
+ "signature": "scissors($corners)",
1510
+ "summary": "Cuts the corners off an element with clip-path.",
1511
+ "examples": [
1512
+ ".a { @include scissors(12px); }",
1513
+ ".a { @include scissors(4px 8px 12px 16px); }"
1514
+ ],
1515
+ "rejects": [
1516
+ ".a { @include scissors(5px 10px); }",
1517
+ ".a { @include scissors(nonsense); }",
1518
+ ".a { @include scissors(10deg); }",
1519
+ ".a { @include scissors(4px 8px 12px 1x); }"
1520
+ ]
1521
+ },
1522
+ {
1523
+ "name": "screen-agent",
1524
+ "kind": "mixin",
1525
+ "arguments": [
1526
+ {
1527
+ "name": "$resolution",
1528
+ "required": true,
1529
+ "accepts": [
1530
+ "1x, 2x or 3x",
1531
+ "a raw resolution in dpi, dpcm, dppx or x, such as 120dpi, or a calculation; a bare number, a length and a negative resolution are refused, because the query would never match"
1532
+ ]
1533
+ }
1534
+ ],
1535
+ "file": "scss/library/_screen-agent.scss",
1536
+ "signature": "screen-agent($resolution)",
1537
+ "summary": "Media query targeting a screen pixel density.",
1538
+ "examples": [
1539
+ ".a { @include screen-agent(\"2x\") { background-image: url(\"/img/a@2x.png\"); } }"
1540
+ ],
1541
+ "rejects": [
1542
+ ".a { @include screen-agent(var(--density)) { color: red; } }",
1543
+ ".a { @include screen-agent(\"huge\") { color: red; } }",
1544
+ ".a { @include screen-agent(2) { color: red; } }",
1545
+ ".a { @include screen-agent(10px) { color: red; } }",
1546
+ ".a { @include screen-agent(-1dppx) { color: red; } }"
1547
+ ]
1548
+ },
1549
+ {
1550
+ "name": "sizer",
1551
+ "kind": "mixin",
1552
+ "arguments": [
1553
+ {
1554
+ "name": "$width",
1555
+ "required": true,
1556
+ "accepts": [
1557
+ "a length"
1558
+ ]
1559
+ },
1560
+ {
1561
+ "name": "$height",
1562
+ "default": "$width",
1563
+ "accepts": [
1564
+ "a length; defaults to the width"
1565
+ ]
1566
+ }
1567
+ ],
1568
+ "file": "scss/library/_sizer.scss",
1569
+ "signature": "sizer($width, $height: $width)",
1570
+ "summary": "Sets width and height together; one argument makes a square.",
1571
+ "examples": [
1572
+ ".a { @include sizer(40px); }",
1573
+ ".a { @include sizer(120px, 40px); }"
1574
+ ],
1575
+ "rejects": [
1576
+ ".a { @include sizer(huge); }",
1577
+ ".a { @include sizer(40); }",
1578
+ ".a { @include sizer(120px, 10deg); }",
1579
+ ".a { @include sizer(-40px); }",
1580
+ ".a { @include sizer(\"40px\"); }"
1581
+ ]
1582
+ },
1583
+ {
1584
+ "name": "smartphone",
1585
+ "kind": "mixin",
1586
+ "arguments": [
1587
+ {
1588
+ "name": "$device",
1589
+ "required": true,
1590
+ "accepts": [
1591
+ "a key from $map-for-smartphones, such as iPhone11"
1592
+ ]
1593
+ },
1594
+ {
1595
+ "name": "$orientation",
1596
+ "default": "null",
1597
+ "accepts": [
1598
+ "portrait",
1599
+ "landscape",
1600
+ "null for portrait"
1601
+ ]
1602
+ }
1603
+ ],
1604
+ "file": "scss/library/_smartphone.scss",
1605
+ "signature": "smartphone($device, $orientation: null)",
1606
+ "summary": "Media query targeting a known smartphone by device dimensions.",
1607
+ "examples": [
1608
+ ".a { @include smartphone(\"iPhone11\") { display: none; } }",
1609
+ ".a { @include smartphone(\"iPhone11\", landscape) { display: none; } }"
1610
+ ],
1611
+ "rejects": [
1612
+ ".a { @include smartphone(Nokia3310) { display: none; } }",
1613
+ ".a { @include smartphone(\"iPhone11\", sideways) { display: none; } }"
1614
+ ]
1615
+ },
1616
+ {
1617
+ "name": "sprite",
1618
+ "kind": "mixin",
1619
+ "arguments": [
1620
+ {
1621
+ "name": "$params",
1622
+ "variadic": true,
1623
+ "accepts": [
1624
+ "an image path ending in .png, .jpg or .svg",
1625
+ "a background position",
1626
+ "both, image first, where the image is one path as a string"
1627
+ ]
1628
+ }
1629
+ ],
1630
+ "file": "scss/library/_sprite.scss",
1631
+ "signature": "sprite($params...)",
1632
+ "summary": "Sets up an element as a sprite tile: an image, a background position, or both.",
1633
+ "examples": [
1634
+ ".icon { @include sprite(\"/img/sprite.png\"); }",
1635
+ ".icon { @include sprite(\"/img/sprite.png\", 0 -40px); }",
1636
+ ".icon { @include sprite(0 -40px); }"
1637
+ ],
1638
+ "rejects": [
1639
+ ".icon { @include sprite(\"/img/sprite.txt\"); }",
1640
+ ".icon { @include sprite(\"/img/a.png\" \"/img/b.png\", 0 -40px); }",
1641
+ ".icon { @include sprite(42, 0 -40px); }",
1642
+ ".icon { @include sprite(0 red); }",
1643
+ ".icon { @include sprite(\"/img/sprite.png\", 10deg); }",
1644
+ ".icon { @include sprite(\"/img/sprite.png\", 1); }",
1645
+ ".icon { @include sprite(\"/img/sprite.png\", 10px 20px 30px 40px); }",
1646
+ ".icon { @include sprite(\"/img/sprite.png\", auto); }"
1647
+ ]
1648
+ },
1649
+ {
1650
+ "name": "stretched-link",
1651
+ "kind": "mixin",
1652
+ "arguments": [
1653
+ {
1654
+ "name": "$value",
1655
+ "default": "\"before\"",
1656
+ "accepts": [
1657
+ "before",
1658
+ "after"
1659
+ ]
1660
+ }
1661
+ ],
1662
+ "file": "scss/library/_stretched-link.scss",
1663
+ "signature": "stretched-link($value: \"before\")",
1664
+ "summary": "Expands a link to cover its positioned parent, so the whole card is clickable.",
1665
+ "examples": [
1666
+ ".card a { @include stretched-link; }",
1667
+ ".card a { @include stretched-link(\"after\"); }"
1668
+ ],
1669
+ "rejects": [
1670
+ ".card a { @include stretched-link(middle); }"
1671
+ ]
1672
+ },
1673
+ {
1674
+ "name": "tablet",
1675
+ "kind": "mixin",
1676
+ "arguments": [
1677
+ {
1678
+ "name": "$device",
1679
+ "required": true,
1680
+ "accepts": [
1681
+ "a key from $map-for-tablets, such as iPadPro"
1682
+ ]
1683
+ },
1684
+ {
1685
+ "name": "$orientation",
1686
+ "default": "null",
1687
+ "accepts": [
1688
+ "portrait",
1689
+ "landscape",
1690
+ "null for portrait"
1691
+ ]
1692
+ }
1693
+ ],
1694
+ "file": "scss/library/_tablet.scss",
1695
+ "signature": "tablet($device, $orientation: null)",
1696
+ "summary": "Media query targeting a known tablet by device dimensions.",
1697
+ "examples": [
1698
+ ".a { @include tablet(\"iPadPro\") { display: none; } }",
1699
+ ".a { @include tablet(\"iPad\", landscape) { display: none; } }"
1700
+ ],
1701
+ "rejects": [
1702
+ ".a { @include tablet(Surface) { display: none; } }"
1703
+ ]
1704
+ },
1705
+ {
1706
+ "name": "text-gradient",
1707
+ "kind": "mixin",
1708
+ "arguments": [
1709
+ {
1710
+ "name": "$colors",
1711
+ "required": true,
1712
+ "accepts": [
1713
+ "one or more colour stops, in the forms the gradient mixin takes",
1714
+ "a stop the browser drops is refused, because the gradient and the transparent text would go with it",
1715
+ "a single colour warns"
1716
+ ]
1717
+ },
1718
+ {
1719
+ "name": "$type",
1720
+ "default": "linear",
1721
+ "accepts": [
1722
+ "linear, the default",
1723
+ "radial",
1724
+ "conic"
1725
+ ]
1726
+ },
1727
+ {
1728
+ "name": "$direction",
1729
+ "default": "null",
1730
+ "accepts": [
1731
+ "linear only",
1732
+ "a direction name such as top or bottom-left",
1733
+ "an angle in deg, grad, rad or turn, or 0",
1734
+ "\"to top\" or \"to left top\" as a string",
1735
+ "var() or calc()"
1736
+ ]
1737
+ },
1738
+ {
1739
+ "name": "$shape",
1740
+ "default": "null",
1741
+ "accepts": [
1742
+ "radial only, circle or ellipse with an optional size"
1743
+ ]
1744
+ },
1745
+ {
1746
+ "name": "$position",
1747
+ "default": "null",
1748
+ "accepts": [
1749
+ "radial or conic, a position name or at followed by a position"
1750
+ ]
1751
+ },
1752
+ {
1753
+ "name": "$from",
1754
+ "default": "null",
1755
+ "accepts": [
1756
+ "conic only, an angle"
1757
+ ]
1758
+ },
1759
+ {
1760
+ "name": "$in",
1761
+ "default": "null",
1762
+ "accepts": [
1763
+ "a colour space such as oklab, or a polar one with a hue method",
1764
+ "the gradient is written once without the space first, for a browser that does not know it"
1765
+ ]
1766
+ },
1767
+ {
1768
+ "name": "$repeating",
1769
+ "default": "false",
1770
+ "accepts": [
1771
+ "false, the default",
1772
+ "true"
1773
+ ]
1774
+ }
1775
+ ],
1776
+ "file": "scss/library/_text-gradient.scss",
1777
+ "signature": "text-gradient($colors, $type: linear, $direction: null, $shape: null, $position: null, $from: null, $in: null, $repeating: false)",
1778
+ "summary": "Fills the text with a gradient through background-clip: text. It takes the gradient mixin's arguments, colours first: a linear, radial or conic gradient, plain or repeating, with an optional colour space.",
1779
+ "examples": [
1780
+ ".a { @include text-gradient((red, blue), $direction: top); }",
1781
+ ".a { @include text-gradient(blue yellow, $direction: right, $in: oklab); }",
1782
+ ".a { @include text-gradient(red yellow lime cyan blue magenta red, conic); }"
1783
+ ],
1784
+ "rejects": [
1785
+ ".a { @include text-gradient(\"top\", (red, blue)); }",
1786
+ ".a { @include text-gradient(red blue, $direction: sideways); }",
1787
+ ".a { @include text-gradient((huge, blue)); }",
1788
+ ".a { @include text-gradient((\"red\", blue)); }",
1789
+ ".a { @include text-gradient(red blue, $from: 45deg); }"
1790
+ ],
1791
+ "warns": [
1792
+ ".a { @include text-gradient(red); }"
1793
+ ]
1794
+ },
1795
+ {
1796
+ "name": "text-image",
1797
+ "kind": "mixin",
1798
+ "arguments": [
1799
+ {
1800
+ "name": "$image",
1801
+ "default": "null",
1802
+ "accepts": [
1803
+ "an image path, as a string; a list, a number, a colour or a boolean is refused",
1804
+ "var(), url(), image-set() or a gradient, written as they are rather than wrapped in url()"
1805
+ ]
1806
+ }
1807
+ ],
1808
+ "file": "scss/library/_text-image.scss",
1809
+ "signature": "text-image($image: null)",
1810
+ "summary": "Fills the text with an image via background-clip.",
1811
+ "examples": [
1812
+ ".a { @include text-image(\"/img/t.png\"); }",
1813
+ ".a { @include text-image(var(--texture)); }"
1814
+ ],
1815
+ "rejects": [
1816
+ ".a { @include text-image(16 9); }",
1817
+ ".a { @include text-image(#ff0000); }"
1818
+ ]
1819
+ },
1820
+ {
1821
+ "name": "text-selection",
1822
+ "kind": "mixin",
1823
+ "arguments": [
1824
+ {
1825
+ "name": "$value",
1826
+ "default": "null",
1827
+ "accepts": [
1828
+ "\"only\" inside a selector to affect just that element",
1829
+ "null for the element and its descendants"
1830
+ ]
1831
+ }
1832
+ ],
1833
+ "file": "scss/library/_text-selection.scss",
1834
+ "signature": "text-selection($value: null)",
1835
+ "summary": "Styles the ::selection pseudo-element.",
1836
+ "examples": [
1837
+ "@include text-selection { background: yellow; }",
1838
+ ".a { @include text-selection(\"only\") { background: yellow; } }"
1839
+ ],
1840
+ "rejects": [
1841
+ ".a { @include text-selection(bogus) { background: yellow; } }"
1842
+ ]
1843
+ },
1844
+ {
1845
+ "name": "text-shadow",
1846
+ "kind": "mixin",
1847
+ "arguments": [
1848
+ {
1849
+ "name": "$params",
1850
+ "variadic": true,
1851
+ "accepts": [
1852
+ "one or more groups of direction, colour and size"
1853
+ ]
1854
+ }
1855
+ ],
1856
+ "file": "scss/library/_text-shadow.scss",
1857
+ "signature": "text-shadow($params...)",
1858
+ "summary": "Layered text shadows built from a direction, a colour and an offset.",
1859
+ "examples": [
1860
+ ".a { @include text-shadow(bottom-right red 5px); }"
1861
+ ],
1862
+ "rejects": [
1863
+ ".a { @include text-shadow(42); }",
1864
+ ".a { @include text-shadow(top red); }"
1865
+ ]
1866
+ },
1867
+ {
1868
+ "name": "text-stroke",
1869
+ "kind": "mixin",
1870
+ "arguments": [
1871
+ {
1872
+ "name": "$fallback-color",
1873
+ "default": "black",
1874
+ "accepts": [
1875
+ "a colour for browsers without text-stroke",
1876
+ "each colour accepts a colour, currentColor, a system colour, a function such as var() or light-dark(), a CSS-wide keyword, or null to leave its declaration out"
1877
+ ]
1878
+ },
1879
+ {
1880
+ "name": "$color",
1881
+ "default": "transparent",
1882
+ "accepts": [
1883
+ "the text fill colour",
1884
+ "a word that is not a colour, a quoted colour, a length or two colours are refused"
1885
+ ]
1886
+ },
1887
+ {
1888
+ "name": "$stroke-color",
1889
+ "default": "black",
1890
+ "accepts": [
1891
+ "the outline colour"
1892
+ ]
1893
+ },
1894
+ {
1895
+ "name": "$stroke-width",
1896
+ "default": "1px",
1897
+ "accepts": [
1898
+ "a length"
1899
+ ]
1900
+ }
1901
+ ],
1902
+ "file": "scss/library/_text-stroke.scss",
1903
+ "signature": "text-stroke($fallback-color: black, $color: transparent, $stroke-color: black, $stroke-width: 1px)",
1904
+ "summary": "Outlines text using the webkit text-stroke properties.",
1905
+ "examples": [
1906
+ ".a { @include text-stroke; }",
1907
+ ".a { @include text-stroke(black, transparent, red, 2px); }"
1908
+ ],
1909
+ "rejects": [
1910
+ ".a { @include text-stroke(huge); }",
1911
+ ".a { @include text-stroke(black, \"red\"); }",
1912
+ ".a { @include text-stroke(black, transparent, 10px); }",
1913
+ ".a { @include text-stroke(black, transparent, red blue); }",
1914
+ ".a { @include text-stroke(black, transparent, red, huge); }",
1915
+ ".a { @include text-stroke(black, transparent, red, 5%); }",
1916
+ ".a { @include text-stroke(black, transparent, red, -1px); }",
1917
+ ".a { @include text-stroke(black, transparent, red, 2); }"
1918
+ ]
1919
+ },
1920
+ {
1921
+ "name": "tokens",
1922
+ "kind": "mixin",
1923
+ "arguments": [
1924
+ {
1925
+ "name": "$map",
1926
+ "required": true,
1927
+ "accepts": [
1928
+ "a map of names to values, where a value is any CSS value: a colour, a length, a font stack, a shadow, a duration, calc() or clamp()",
1929
+ "a value of null, which is skipped",
1930
+ "a value that references another token, such as var(--blue-500)"
1931
+ ]
1932
+ },
1933
+ {
1934
+ "name": "$prefix",
1935
+ "default": "null",
1936
+ "accepts": [
1937
+ "null, the default, for no prefix",
1938
+ "a name, joined to each property name with a hyphen"
1939
+ ]
1940
+ }
1941
+ ],
1942
+ "file": "scss/library/_tokens.scss",
1943
+ "signature": "tokens($map, $prefix: null)",
1944
+ "summary": "Writes a Sass map out as CSS custom properties, for any kind of token: colours, spacing, sizes, radii, type, shadows, durations. With the prefix space, (4: 1rem) becomes --space-4: 1rem. A null value is skipped, and a quoted string keeps its quotes.",
1945
+ "examples": [
1946
+ ":root { @include tokens((1: 0.25rem, 2: 0.5rem, 4: 1rem), space); @include tokens((md: 8px, full: 9999px), radius); }",
1947
+ ":root { @include tokens((md: 0 4px 12px rgba(24, 24, 27, 0.08)), shadow); @include tokens((fast: 150ms, ease: cubic-bezier(0.2, 0, 0, 1)), motion); }",
1948
+ ":root { @include tokens((bg: #fff, text: #111), color); }",
1949
+ ":root { @include tokens((blue-500: #3b82f6, blue-600: #2563eb)); }",
1950
+ ":root { @include tokens((red: #ef4444, 500: #3b82f6), blue); }",
1951
+ "[data-theme=\"dark\"] { @include tokens((bg: #09090b, accent: var(--blue-500)), color); }",
1952
+ ":root { @include tokens((body: (\"Readex Pro\", sans-serif), label: \"New\", focus: null), font); }"
1953
+ ],
1954
+ "rejects": [
1955
+ ":root { @include tokens(#fff); }",
1956
+ ":root { @include tokens((brand: (500: #3b82f6)), color); }",
1957
+ ":root { @include tokens((bg: #fff), (color, text)); }",
1958
+ ":root { @include tokens((\"brand color\": #f00)); }",
1959
+ "@include tokens((bg: #fff));"
1960
+ ]
1961
+ },
1962
+ {
1963
+ "name": "triangle",
1964
+ "kind": "mixin",
1965
+ "arguments": [
1966
+ {
1967
+ "name": "$direction",
1968
+ "default": "\"bottom\"",
1969
+ "accepts": [
1970
+ "top",
1971
+ "top-right",
1972
+ "right",
1973
+ "bottom-right",
1974
+ "bottom",
1975
+ "bottom-left",
1976
+ "left",
1977
+ "top-left",
1978
+ "inline-start, inline-end, block-start or block-end, which follow the writing direction"
1979
+ ]
1980
+ },
1981
+ {
1982
+ "name": "$color",
1983
+ "default": "black",
1984
+ "accepts": [
1985
+ "a Sass colour, such as red, #333 or oklch(70% 0.1 200)",
1986
+ "currentColor",
1987
+ "a system colour such as Canvas",
1988
+ "var(), color-mix(), light-dark(), contrast-color() or rgb(from ...), which CSS resolves",
1989
+ "a CSS-wide keyword is refused, because it is invalid inside the border-color shorthand"
1990
+ ]
1991
+ },
1992
+ {
1993
+ "name": "$size",
1994
+ "default": "10px 8px",
1995
+ "accepts": [
1996
+ "one length, or two lengths as width then height",
1997
+ "var(), env() or a calculation in place of any length"
1998
+ ]
1999
+ }
2000
+ ],
2001
+ "file": "scss/library/_triangle.scss",
2002
+ "signature": "triangle($direction: \"bottom\", $color: black, $size: 10px 8px)",
2003
+ "summary": "Draws a CSS triangle out of borders, pointing in a given direction.",
2004
+ "examples": [
2005
+ ".caret { @include triangle(\"bottom\", black, 10px 8px); }",
2006
+ ".arrow { @include triangle(\"left\", red); }",
2007
+ ".arrow { @include triangle(\"right\", var(--accent), 6px 8px); }",
2008
+ ".arrow { @include triangle(\"right\", currentColor); }",
2009
+ ".arrow { @include triangle(\"top\", color-mix(in srgb, red 50%, blue)); }",
2010
+ ".arrow { @include triangle(\"bottom\", currentColor, var(--caret-w) var(--caret-h)); }",
2011
+ ".next { @include triangle(\"inline-end\", currentColor, 8px 12px); }",
2012
+ ".sort { @include triangle(\"block-start\", currentColor); }"
2013
+ ],
2014
+ "rejects": [
2015
+ ".caret { @include triangle(sideways); }",
2016
+ ".caret { @include triangle(\"top\", notacolor); }",
2017
+ ".caret { @include triangle(\"top\", url(a.png)); }",
2018
+ ".caret { @include triangle(\"top\", red, nonsense); }",
2019
+ ".caret { @include triangle(\"top\", -webkit-fill-available); }",
2020
+ ".caret { @include triangle(\"top\", red, 5%); }",
2021
+ ".caret { @include triangle(\"top\", red, -10px); }",
2022
+ ".caret { @include triangle(\"top\", red, thin); }",
2023
+ ".caret { @include triangle(\"top\", red, 10); }",
2024
+ ".caret { @include triangle(\"top\", red, 10px 10deg); }"
2025
+ ]
2026
+ },
2027
+ {
2028
+ "name": "clearUnit",
2029
+ "kind": "function",
2030
+ "arguments": [
2031
+ {
2032
+ "name": "$value",
2033
+ "required": true,
2034
+ "accepts": [
2035
+ "any number with a unit"
2036
+ ]
2037
+ }
2038
+ ],
2039
+ "file": "scss/utilities/_clear-unit.scss",
2040
+ "signature": "clearUnit($value)",
2041
+ "summary": "Strips the unit off a number, returning it unitless.",
2042
+ "examples": [
2043
+ ".a { line-height: clearUnit(24px); }"
2044
+ ],
2045
+ "rejects": [
2046
+ ".a { line-height: clearUnit(nonsense); }"
2047
+ ]
2048
+ },
2049
+ {
2050
+ "name": "clearWhitespace",
2051
+ "kind": "function",
2052
+ "arguments": [
2053
+ {
2054
+ "name": "$string",
2055
+ "required": true,
2056
+ "accepts": [
2057
+ "any string"
2058
+ ]
2059
+ }
2060
+ ],
2061
+ "file": "scss/utilities/_clear-whitespace.scss",
2062
+ "signature": "clearWhitespace($string)",
2063
+ "summary": "Removes every space from a string.",
2064
+ "examples": [
2065
+ ".a { content: clearWhitespace(\"a b c\"); }"
2066
+ ],
2067
+ "rejects": [
2068
+ ".a { --x: #{clearWhitespace(42)}; }"
2069
+ ]
2070
+ },
2071
+ {
2072
+ "name": "convertToEm",
2073
+ "kind": "function",
2074
+ "arguments": [
2075
+ {
2076
+ "name": "$value",
2077
+ "required": true,
2078
+ "accepts": [
2079
+ "a pixel length"
2080
+ ]
2081
+ }
2082
+ ],
2083
+ "file": "scss/utilities/_convert-to-em.scss",
2084
+ "signature": "convertToEm($value)",
2085
+ "summary": "Converts a pixel length to em, against a 16px base.",
2086
+ "examples": [
2087
+ ".a { margin: convertToEm(24px); }"
2088
+ ],
2089
+ "rejects": [
2090
+ ".a { margin: convertToEm(nonsense); }",
2091
+ ".a { margin: convertToEm(24); }"
2092
+ ]
2093
+ },
2094
+ {
2095
+ "name": "convertToNumber",
2096
+ "kind": "function",
2097
+ "arguments": [
2098
+ {
2099
+ "name": "$value",
2100
+ "required": true,
2101
+ "accepts": [
2102
+ "a string containing only digits"
2103
+ ]
2104
+ }
2105
+ ],
2106
+ "file": "scss/utilities/_convert-to-number.scss",
2107
+ "signature": "convertToNumber($value)",
2108
+ "summary": "Parses a string of digits into a number.",
2109
+ "examples": [
2110
+ ".a { z-index: convertToNumber(\"42\"); }"
2111
+ ],
2112
+ "rejects": [
2113
+ ".a { --x: #{convertToNumber(42)}; }",
2114
+ ".a { z-index: convertToNumber(\"4a\"); }",
2115
+ ".a { z-index: convertToNumber(\"\"); }"
2116
+ ]
2117
+ },
2118
+ {
2119
+ "name": "fillNulls",
2120
+ "kind": "function",
2121
+ "arguments": [
2122
+ {
2123
+ "name": "$value",
2124
+ "required": true,
2125
+ "accepts": [
2126
+ "a list that may contain nulls"
2127
+ ]
2128
+ },
2129
+ {
2130
+ "name": "$seperation",
2131
+ "default": "comma",
2132
+ "accepts": [
2133
+ "comma",
2134
+ "space"
2135
+ ]
2136
+ },
2137
+ {
2138
+ "name": "$skip",
2139
+ "default": "false",
2140
+ "accepts": [
2141
+ "true to leave nulls in place instead of using 0"
2142
+ ]
2143
+ }
2144
+ ],
2145
+ "file": "scss/utilities/_fill-nulls.scss",
2146
+ "signature": "fillNulls($value, $seperation: comma, $skip: false)",
2147
+ "summary": "Replaces null entries in a list with 0, or drops them.",
2148
+ "examples": [
2149
+ ".a { margin: fillNulls(1px null 3px null, space); }"
2150
+ ],
2151
+ "rejects": [
2152
+ ".a { --x: #{fillNulls(1px null, nonsense)}; }"
2153
+ ]
2154
+ },
2155
+ {
2156
+ "name": "fluid",
2157
+ "kind": "function",
2158
+ "arguments": [
2159
+ {
2160
+ "name": "$min",
2161
+ "required": true,
2162
+ "accepts": [
2163
+ "a length in px or rem, the value at $min-viewport"
2164
+ ]
2165
+ },
2166
+ {
2167
+ "name": "$max",
2168
+ "required": true,
2169
+ "accepts": [
2170
+ "a length in px or rem, the value at $max-viewport, no smaller than $min"
2171
+ ]
2172
+ },
2173
+ {
2174
+ "name": "$min-viewport",
2175
+ "default": "320px",
2176
+ "accepts": [
2177
+ "a length in px or rem, the width below which the value stops shrinking"
2178
+ ]
2179
+ },
2180
+ {
2181
+ "name": "$max-viewport",
2182
+ "default": "1280px",
2183
+ "accepts": [
2184
+ "a length in px or rem, larger than $min-viewport"
2185
+ ]
2186
+ }
2187
+ ],
2188
+ "file": "scss/utilities/_fluid.scss",
2189
+ "signature": "fluid($min, $max, $min-viewport: 320px, $max-viewport: 1280px)",
2190
+ "summary": "A clamp() value that grows with the viewport between two widths, then stops. The preferred value keeps a rem term rather than being pure vw, because a vw-only value ignores browser text zoom and fails WCAG 1.4.4. It is a function rather than a mixin because the value is the hard part and belongs to any property, not only font-size.",
2191
+ "examples": [
2192
+ ".title { font-size: fluid(24px, 48px); }",
2193
+ ".title { font-size: fluid(1rem, 3rem, 320px, 1200px); }",
2194
+ ".section { padding: fluid(16px, 64px) fluid(8px, 40px); }",
2195
+ ".stack { gap: fluid(0.5rem, 2rem); }"
2196
+ ],
2197
+ "rejects": [
2198
+ ".title { font-size: fluid(16px, 24px, 1280px, 320px); }",
2199
+ ".title { font-size: fluid(40px, 20px); }",
2200
+ ".title { font-size: fluid(16, 24); }",
2201
+ ".title { font-size: fluid(1em, 2em); }"
2202
+ ]
2203
+ },
2204
+ {
2205
+ "name": "fontSizer",
2206
+ "kind": "function",
2207
+ "arguments": [
2208
+ {
2209
+ "name": "$size",
2210
+ "required": true,
2211
+ "accepts": [
2212
+ "a length"
2213
+ ]
2214
+ },
2215
+ {
2216
+ "name": "$time",
2217
+ "required": true,
2218
+ "accepts": [
2219
+ "a unitless multiplier"
2220
+ ]
2221
+ }
2222
+ ],
2223
+ "file": "scss/utilities/_font-sizer.scss",
2224
+ "signature": "fontSizer($size, $time)",
2225
+ "summary": "Multiplies a size by a factor. Handy for a modular scale.",
2226
+ "examples": [
2227
+ ".a { font-size: fontSizer(16px, 1.5); }"
2228
+ ],
2229
+ "rejects": [
2230
+ ".a { font-size: fontSizer(nonsense, 1.5); }",
2231
+ ".a { font-size: fontSizer(16px, 1px); }"
2232
+ ]
2233
+ },
2234
+ {
2235
+ "name": "fontSource",
2236
+ "kind": "function",
2237
+ "arguments": [
2238
+ {
2239
+ "name": "$font-family",
2240
+ "required": true,
2241
+ "accepts": [
2242
+ "the family name"
2243
+ ]
2244
+ },
2245
+ {
2246
+ "name": "$file-path",
2247
+ "required": true,
2248
+ "accepts": [
2249
+ "path without an extension"
2250
+ ]
2251
+ },
2252
+ {
2253
+ "name": "$file-formats",
2254
+ "required": true,
2255
+ "accepts": [
2256
+ "one of eot, woff2, woff, ttf, svg"
2257
+ ]
2258
+ }
2259
+ ],
2260
+ "file": "scss/utilities/_font-source.scss",
2261
+ "signature": "fontSource($font-family, $file-path, $file-formats)",
2262
+ "summary": "Builds one src entry for an @font-face rule.",
2263
+ "examples": [
2264
+ ".a { content: \"#{fontSource(\"Inter\", \"/fonts/inter\", woff2)}\"; }"
2265
+ ],
2266
+ "rejects": []
2267
+ },
2268
+ {
2269
+ "name": "gradientValue",
2270
+ "kind": "function",
2271
+ "arguments": [
2272
+ {
2273
+ "name": "$colors",
2274
+ "required": true,
2275
+ "accepts": [
2276
+ "the colour stops, in the forms the gradient mixin takes",
2277
+ "a single colour warns, because browsers before Chrome 135, Firefox 136 and Safari 18.4 drop that gradient"
2278
+ ]
2279
+ },
2280
+ {
2281
+ "name": "$type",
2282
+ "default": "linear",
2283
+ "accepts": [
2284
+ "linear, the default",
2285
+ "radial",
2286
+ "conic"
2287
+ ]
2288
+ },
2289
+ {
2290
+ "name": "$direction",
2291
+ "default": "null",
2292
+ "accepts": [
2293
+ "linear only, in the forms the gradient mixin takes"
2294
+ ]
2295
+ },
2296
+ {
2297
+ "name": "$shape",
2298
+ "default": "null",
2299
+ "accepts": [
2300
+ "radial only, circle or ellipse with an optional size"
2301
+ ]
2302
+ },
2303
+ {
2304
+ "name": "$position",
2305
+ "default": "null",
2306
+ "accepts": [
2307
+ "radial or conic, a position name or at followed by a position"
2308
+ ]
2309
+ },
2310
+ {
2311
+ "name": "$from",
2312
+ "default": "null",
2313
+ "accepts": [
2314
+ "conic only, an angle"
2315
+ ]
2316
+ },
2317
+ {
2318
+ "name": "$in",
2319
+ "default": "null",
2320
+ "accepts": [
2321
+ "a colour space, with a hue method for a polar one",
2322
+ "var()"
2323
+ ]
2324
+ },
2325
+ {
2326
+ "name": "$repeating",
2327
+ "default": "false",
2328
+ "accepts": [
2329
+ "false, the default",
2330
+ "true"
2331
+ ]
2332
+ }
2333
+ ],
2334
+ "file": "scss/utilities/_gradient-value.scss",
2335
+ "signature": "gradientValue($colors, $type: linear, $direction: null, $shape: null, $position: null, $from: null, $in: null, $repeating: false)",
2336
+ "summary": "The gradient mixin's gradient as a value, for layering it with an image in one background-image, or using it as a mask-image or border-image. It takes the same arguments and refuses the same input, but cannot write the fallback the mixin writes before a gradient with $in.",
2337
+ "examples": [
2338
+ ".a { background-image: gradientValue((rgba(0, 0, 0, 0.75), transparent), $direction: top), url(\"/img/hero.jpg\"); }",
2339
+ ".a { mask-image: gradientValue((#000 60%, transparent)); }",
2340
+ ".a { border: 4px solid; border-image: gradientValue((red, blue), $direction: right) 1; }"
2341
+ ],
2342
+ "rejects": [
2343
+ ".a { background-image: gradientValue((red, blue), $direction: sideways); }",
2344
+ ".a { background-image: gradientValue((red, blue), $shape: circle); }",
2345
+ ".a { background-image: gradientValue((red 10px, blue), conic); }",
2346
+ ".a { background-image: gradientValue((red, blue), $in: rgb); }"
2347
+ ],
2348
+ "warns": [
2349
+ ".a { background-image: gradientValue(red); }"
2350
+ ]
2351
+ },
2352
+ {
2353
+ "name": "isColor",
2354
+ "kind": "function",
2355
+ "arguments": [
2356
+ {
2357
+ "name": "$value",
2358
+ "required": true,
2359
+ "accepts": [
2360
+ "a colour, or a list of colours"
2361
+ ]
2362
+ }
2363
+ ],
2364
+ "file": "scss/utilities/_is-color.scss",
2365
+ "signature": "isColor($value)",
2366
+ "summary": "Returns the value if every item in it is a colour, and errors otherwise.",
2367
+ "examples": [
2368
+ ".a { color: isColor(red); }"
2369
+ ],
2370
+ "rejects": [
2371
+ ".a { color: isColor(nonsense); }"
2372
+ ]
2373
+ },
2374
+ {
2375
+ "name": "isGutter",
2376
+ "kind": "function",
2377
+ "arguments": [
2378
+ {
2379
+ "name": "$value",
2380
+ "required": true,
2381
+ "accepts": [
2382
+ "any value"
2383
+ ]
2384
+ }
2385
+ ],
2386
+ "file": "scss/utilities/_is-gutter.scss",
2387
+ "signature": "isGutter($value)",
2388
+ "summary": "True for anything that can sit where a CSS length is expected: a number, a calculation, or a CSS function such as var().",
2389
+ "examples": [
2390
+ ".a { --x: #{isGutter(20px)}; }",
2391
+ ".a { --x: #{isGutter(var(--gap))}; }"
2392
+ ],
2393
+ "rejects": []
2394
+ },
2395
+ {
2396
+ "name": "isNumber",
2397
+ "kind": "function",
2398
+ "arguments": [
2399
+ {
2400
+ "name": "$value",
2401
+ "required": true,
2402
+ "accepts": [
2403
+ "any value"
2404
+ ]
2405
+ }
2406
+ ],
2407
+ "file": "scss/utilities/_is-number.scss",
2408
+ "signature": "isNumber($value)",
2409
+ "summary": "Returns the value if it is a number.",
2410
+ "examples": [
2411
+ ".a { z-index: isNumber(5); }"
2412
+ ],
2413
+ "rejects": []
2414
+ },
2415
+ {
2416
+ "name": "isTime",
2417
+ "kind": "function",
2418
+ "arguments": [
2419
+ {
2420
+ "name": "$value",
2421
+ "required": true,
2422
+ "accepts": [
2423
+ "a duration such as 0.2s or 300ms, or 0"
2424
+ ]
2425
+ }
2426
+ ],
2427
+ "file": "scss/utilities/_is-time.scss",
2428
+ "signature": "isTime($value)",
2429
+ "summary": "Returns the value if it is a time in s or ms, and errors otherwise.",
2430
+ "examples": [
2431
+ ".a { animation-duration: isTime(0.4s); }"
2432
+ ],
2433
+ "rejects": [
2434
+ ".a { animation-duration: isTime(400px); }"
2435
+ ]
2436
+ },
2437
+ {
2438
+ "name": "mapDeepGet",
2439
+ "kind": "function",
2440
+ "arguments": [
2441
+ {
2442
+ "name": "$map",
2443
+ "required": true,
2444
+ "accepts": [
2445
+ "a map"
2446
+ ]
2447
+ },
2448
+ {
2449
+ "name": "$keys",
2450
+ "variadic": true,
2451
+ "accepts": [
2452
+ "one key per level of nesting"
2453
+ ]
2454
+ }
2455
+ ],
2456
+ "file": "scss/utilities/_map-deep-get.scss",
2457
+ "signature": "mapDeepGet($map, $keys...)",
2458
+ "summary": "Reads a value out of a nested map by following a chain of keys.",
2459
+ "examples": [
2460
+ ".a { height: mapDeepGet($map-for-tablets, \"iPadPro\", \"height\"); }"
2461
+ ],
2462
+ "rejects": []
2463
+ },
2464
+ {
2465
+ "name": "pixelify",
2466
+ "kind": "function",
2467
+ "arguments": [
2468
+ {
2469
+ "name": "$value",
2470
+ "required": true,
2471
+ "accepts": [
2472
+ "a number, with or without a unit"
2473
+ ]
2474
+ }
2475
+ ],
2476
+ "file": "scss/utilities/_pixelify.scss",
2477
+ "signature": "pixelify($value)",
2478
+ "summary": "Returns the value with a px unit, adding one if it is missing.",
2479
+ "examples": [
2480
+ ".a { width: pixelify(24); }"
2481
+ ],
2482
+ "rejects": [
2483
+ ".a { --x: #{pixelify(nonsense)}; }"
2484
+ ]
2485
+ },
2486
+ {
2487
+ "name": "pseudoSelector",
2488
+ "kind": "function",
2489
+ "arguments": [
2490
+ {
2491
+ "name": "$elements",
2492
+ "required": true,
2493
+ "accepts": [
2494
+ "a list of selectors"
2495
+ ]
2496
+ },
2497
+ {
2498
+ "name": "$pseudo",
2499
+ "default": "null",
2500
+ "accepts": [
2501
+ "a pseudo-class name, without the colon"
2502
+ ]
2503
+ }
2504
+ ],
2505
+ "file": "scss/utilities/_pseudo-selector.scss",
2506
+ "signature": "pseudoSelector($elements, $pseudo: null)",
2507
+ "summary": "Appends a pseudo-class to every selector in a list.",
2508
+ "examples": [
2509
+ ".a { content: \"#{pseudoSelector((\"button\", \"a\"), \"hover\")}\"; }"
2510
+ ],
2511
+ "rejects": []
2512
+ },
2513
+ {
2514
+ "name": "remify",
2515
+ "kind": "function",
2516
+ "arguments": [
2517
+ {
2518
+ "name": "$value",
2519
+ "required": true,
2520
+ "accepts": [
2521
+ "a pixel length"
2522
+ ]
2523
+ }
2524
+ ],
2525
+ "file": "scss/utilities/_remify.scss",
2526
+ "signature": "remify($value)",
2527
+ "summary": "Converts a pixel length to rem, against a 16px root.",
2528
+ "examples": [
2529
+ ".a { font-size: remify(24px); }"
2530
+ ],
2531
+ "rejects": [
2532
+ ".a { font-size: remify(nonsense); }",
2533
+ ".a { font-size: remify(1.5rem); }",
2534
+ ".a { font-size: remify(24); }"
2535
+ ]
2536
+ },
2537
+ {
2538
+ "name": "shade",
2539
+ "kind": "function",
2540
+ "arguments": [
2541
+ {
2542
+ "name": "$color",
2543
+ "required": true,
2544
+ "accepts": [
2545
+ "a colour"
2546
+ ]
2547
+ },
2548
+ {
2549
+ "name": "$percentage",
2550
+ "required": true,
2551
+ "accepts": [
2552
+ "a percentage"
2553
+ ]
2554
+ }
2555
+ ],
2556
+ "file": "scss/utilities/_shade.scss",
2557
+ "signature": "shade($color, $percentage)",
2558
+ "summary": "Mixes a colour towards black by a percentage.",
2559
+ "examples": [
2560
+ ".a { color: shade(red, 20%); }"
2561
+ ],
2562
+ "rejects": [
2563
+ ".a { color: shade(notacolor, 20%); }",
2564
+ ".a { color: shade(var(--x), 20%); }"
2565
+ ]
2566
+ },
2567
+ {
2568
+ "name": "shorthandProperty",
2569
+ "kind": "function",
2570
+ "arguments": [
2571
+ {
2572
+ "name": "$value",
2573
+ "required": true,
2574
+ "accepts": [
2575
+ "one to four values"
2576
+ ]
2577
+ }
2578
+ ],
2579
+ "file": "scss/utilities/_shorthand-property.scss",
2580
+ "signature": "shorthandProperty($value)",
2581
+ "summary": "Expands one to four values into the four-value CSS shorthand order.",
2582
+ "examples": [
2583
+ ".a { margin: shorthandProperty(10px 20px); }"
2584
+ ],
2585
+ "rejects": [
2586
+ ".a { margin: shorthandProperty(1px 2px 3px 4px 5px); }"
2587
+ ]
2588
+ },
2589
+ {
2590
+ "name": "tint",
2591
+ "kind": "function",
2592
+ "arguments": [
2593
+ {
2594
+ "name": "$color",
2595
+ "required": true,
2596
+ "accepts": [
2597
+ "a colour"
2598
+ ]
2599
+ },
2600
+ {
2601
+ "name": "$percentage",
2602
+ "required": true,
2603
+ "accepts": [
2604
+ "a percentage"
2605
+ ]
2606
+ }
2607
+ ],
2608
+ "file": "scss/utilities/_tint.scss",
2609
+ "signature": "tint($color, $percentage)",
2610
+ "summary": "Mixes a colour towards white by a percentage.",
2611
+ "examples": [
2612
+ ".a { color: tint(red, 20%); }"
2613
+ ],
2614
+ "rejects": [
2615
+ ".a { color: tint(notacolor, 20%); }",
2616
+ ".a { color: tint(var(--x), 20%); }"
2617
+ ]
2618
+ },
2619
+ {
2620
+ "name": "validateBreakpoint",
2621
+ "kind": "function",
2622
+ "arguments": [
2623
+ {
2624
+ "name": "$value",
2625
+ "required": true,
2626
+ "accepts": [
2627
+ "a key from $map-for-breakpoints",
2628
+ "a length, a percentage or a CSS function such as var() or min(), returned as it is"
2629
+ ]
2630
+ }
2631
+ ],
2632
+ "file": "scss/utilities/_validate-breakpoint.scss",
2633
+ "signature": "validateBreakpoint($value)",
2634
+ "summary": "Resolves a breakpoint name to its width, passing a length, a percentage or a CSS function through, and refusing a word that is not a key.",
2635
+ "examples": [
2636
+ ".a { width: validateBreakpoint(\"medium\"); }"
2637
+ ],
2638
+ "rejects": [
2639
+ ".a { width: validateBreakpoint(\"huge\"); }",
2640
+ ".a { width: validateBreakpoint(\"small\" \"medium\"); }"
2641
+ ]
2642
+ },
2643
+ {
2644
+ "name": "validateLength",
2645
+ "kind": "function",
2646
+ "arguments": [
2647
+ {
2648
+ "name": "$value",
2649
+ "required": true,
2650
+ "accepts": [
2651
+ "a length with a unit, or auto, inherit, initial, 0",
2652
+ "null, returned as null without a warning"
2653
+ ]
2654
+ }
2655
+ ],
2656
+ "file": "scss/utilities/_validate-length.scss",
2657
+ "signature": "validateLength($value)",
2658
+ "summary": "Returns the value if it is a length or one of auto, inherit, initial, 0. Returns null quietly for null, so a caller can skip a value.",
2659
+ "examples": [
2660
+ ".a { width: validateLength(20px); }"
2661
+ ],
2662
+ "rejects": []
2663
+ },
2664
+ {
2665
+ "name": "validateRatio",
2666
+ "kind": "function",
2667
+ "arguments": [
2668
+ {
2669
+ "name": "$ratio",
2670
+ "required": true,
2671
+ "accepts": [
2672
+ "a string such as \"16/9\" or \"16:9\"",
2673
+ "a unitless number",
2674
+ "null for the 16/9 default",
2675
+ "var(), returned as it is"
2676
+ ]
2677
+ }
2678
+ ],
2679
+ "file": "scss/utilities/_validate-ratio.scss",
2680
+ "signature": "validateRatio($ratio)",
2681
+ "summary": "Turns an aspect ratio into a value for the CSS aspect-ratio property.",
2682
+ "examples": [
2683
+ ".a { aspect-ratio: validateRatio(\"16/9\"); }",
2684
+ ".a { aspect-ratio: validateRatio(1.5); }",
2685
+ ".a { aspect-ratio: validateRatio(var(--ratio)); }"
2686
+ ],
2687
+ "rejects": [
2688
+ ".a { aspect-ratio: validateRatio(16 9); }",
2689
+ ".a { aspect-ratio: validateRatio(\"16 / 9\"); }"
2690
+ ]
2691
+ },
2692
+ {
2693
+ "name": "validateScissors",
2694
+ "kind": "function",
2695
+ "arguments": [
2696
+ {
2697
+ "name": "$value",
2698
+ "required": true,
2699
+ "accepts": [
2700
+ "one to four numbers, with or without units"
2701
+ ]
2702
+ }
2703
+ ],
2704
+ "file": "scss/utilities/_validate-scissors.scss",
2705
+ "signature": "validateScissors($value)",
2706
+ "summary": "Normalises corner values for the scissors mixin, adding px where missing.",
2707
+ "examples": [
2708
+ ".a { content: \"#{validateScissors(12px)}\"; }"
2709
+ ],
2710
+ "rejects": []
2711
+ }
2712
+ ]
2713
+ }