gerillass 2.2.1 → 2.3.1

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 (48) hide show
  1. package/SKILL.md +19 -2
  2. package/gerillass.json +301 -69
  3. package/package.json +1 -1
  4. package/scss/internal/_color-problem.scss +99 -0
  5. package/scss/internal/_color-stops-problem.scss +94 -0
  6. package/scss/internal/_condition-width.scss +22 -0
  7. package/scss/internal/_custom-property-in.scss +25 -0
  8. package/scss/internal/_image-value.scss +68 -0
  9. package/scss/internal/_is-condition-value.scss +94 -0
  10. package/scss/internal/_is-css-function.scss +21 -0
  11. package/scss/internal/_is-size.scss +22 -0
  12. package/scss/internal/_keyword-value.scss +76 -0
  13. package/scss/internal/_length-problem.scss +127 -0
  14. package/scss/internal/_sibling-index.scss +51 -0
  15. package/scss/internal/_words.scss +35 -0
  16. package/scss/library/_adaptive.scss +17 -0
  17. package/scss/library/_after.scss +2 -12
  18. package/scss/library/_background-dots.scss +29 -37
  19. package/scss/library/_background-image.scss +37 -25
  20. package/scss/library/_background-stripes.scss +34 -37
  21. package/scss/library/_before.scss +2 -12
  22. package/scss/library/_border-radius.scss +83 -0
  23. package/scss/library/_brand-logo.scss +10 -24
  24. package/scss/library/_breakpoint.scss +16 -23
  25. package/scss/library/_circle.scss +7 -0
  26. package/scss/library/_columnizer.scss +62 -2
  27. package/scss/library/_container-query.scss +11 -27
  28. package/scss/library/_container.scss +2 -19
  29. package/scss/library/_counter.scss +3 -14
  30. package/scss/library/_ellipsis.scss +78 -1
  31. package/scss/library/_except.scss +15 -0
  32. package/scss/library/_focus-ring.scss +29 -0
  33. package/scss/library/_font-face.scss +117 -1
  34. package/scss/library/_line-clamp.scss +2 -13
  35. package/scss/library/_linear-gradient.scss +7 -0
  36. package/scss/library/_only.scss +16 -0
  37. package/scss/library/_position.scss +63 -12
  38. package/scss/library/_radial-gradient.scss +154 -0
  39. package/scss/library/_resizable.scss +29 -2
  40. package/scss/library/_screen-agent.scss +8 -22
  41. package/scss/library/_sizer.scss +9 -0
  42. package/scss/library/_sprite.scss +65 -0
  43. package/scss/library/_text-gradient.scss +8 -0
  44. package/scss/library/_text-image.scss +2 -23
  45. package/scss/library/_text-stroke.scss +30 -0
  46. package/scss/library/_triangle.scss +25 -56
  47. package/scss/utilities/_validate-breakpoint.scss +32 -6
  48. package/scss/utilities/_validate-scissors.scss +7 -0
package/gerillass.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gerillass",
3
- "version": "2.2.1",
3
+ "version": "2.3.1",
4
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
5
  "homepage": "https://gerillass.com",
6
6
  "documentation": "https://docs.gerillass.com",
@@ -30,7 +30,12 @@
30
30
  ".wrap { @include adaptive; }",
31
31
  ".wrap { @include adaptive(16px); }"
32
32
  ],
33
- "rejects": []
33
+ "rejects": [
34
+ ".wrap { @include adaptive(auto); }",
35
+ ".wrap { @include adaptive(16); }",
36
+ ".wrap { @include adaptive(10deg); }",
37
+ ".wrap { @include adaptive(10px 20px); }"
38
+ ]
34
39
  },
35
40
  {
36
41
  "name": "after",
@@ -207,7 +212,7 @@
207
212
  "name": "$color",
208
213
  "default": "null",
209
214
  "accepts": [
210
- "one colour, or two for the diagonal variant",
215
+ "one colour, or two for the diagonal variant, each a colour, currentColor, a system colour or a function such as var() or light-dark()",
211
216
  "null for a translucent black"
212
217
  ]
213
218
  },
@@ -238,7 +243,7 @@
238
243
  "name": "$image",
239
244
  "default": "null",
240
245
  "accepts": [
241
- "an image path to sit behind the dots",
246
+ "an image path to sit behind the dots, written unquoted unless it holds a space, a parenthesis or a quote, which are quoted",
242
247
  "var(), url(), image-set() or a gradient, written as they are rather than wrapped in url()"
243
248
  ]
244
249
  }
@@ -258,7 +263,14 @@
258
263
  ".a { @include background-dots(red, 1em, 5em, maybe); }",
259
264
  ".a { @include background-dots(red, 1em, 5em, true, 42); }",
260
265
  ".a { @include background-dots(red, nonsense); }",
261
- ".a { @include background-dots(red, 1em, nonsense); }"
266
+ ".a { @include background-dots(red, 1em, nonsense); }",
267
+ ".a { @include background-dots(huge); }",
268
+ ".a { @include background-dots(red 10px); }",
269
+ ".a { @include background-dots(inherit); }",
270
+ ".a { @include background-dots(red, -1em); }",
271
+ ".a { @include background-dots(red, 10deg); }",
272
+ ".a { @include background-dots(red, 2); }",
273
+ ".a { @include background-dots(red, 1em, -5em); }"
262
274
  ]
263
275
  },
264
276
  {
@@ -269,7 +281,7 @@
269
281
  "name": "$image-url",
270
282
  "default": "null",
271
283
  "accepts": [
272
- "an image path",
284
+ "an image path, as a string; a list, a number, a colour or a boolean is refused",
273
285
  "null to filter the element itself instead",
274
286
  "var(), url(), image-set() or a gradient, written as they are rather than wrapped in url()"
275
287
  ]
@@ -278,7 +290,9 @@
278
290
  "name": "$filter-color",
279
291
  "default": "null",
280
292
  "accepts": [
281
- "one colour, or several for a gradient"
293
+ "one colour, or several colour stops for a gradient, in the forms linear-gradient takes",
294
+ "with $image-url null, an image as the overlay layer too: a gradient, url(), image-set() or var()",
295
+ "a word that is not a colour, a quoted colour, a length and a CSS-wide keyword are refused"
282
296
  ]
283
297
  },
284
298
  {
@@ -303,7 +317,14 @@
303
317
  "rejects": [
304
318
  ".a { @include background-image(\"/img/a.png\", (red, blue), sideways); }",
305
319
  ".a { @include background-image(\"/img/a.png\", rgba(0,0,0,0.5), sideways); }",
306
- ".a { @include background-image(null, rgba(0,0,0,0.5), sideways); }"
320
+ ".a { @include background-image(null, rgba(0,0,0,0.5), sideways); }",
321
+ ".a { @include background-image(16 9); }",
322
+ ".a { @include background-image(42); }",
323
+ ".a { @include background-image(\"/img/a.png\", huge); }",
324
+ ".a { @include background-image(\"/img/a.png\", (red, 10%)); }",
325
+ ".a { @include background-image(null, 10px); }",
326
+ ".a { @include background-image(null, inherit); }",
327
+ ".a { @include background-image(\"/img/a.png\", linear-gradient(to top, black, transparent)); }"
307
328
  ]
308
329
  },
309
330
  {
@@ -314,7 +335,7 @@
314
335
  "name": "$color",
315
336
  "default": "null",
316
337
  "accepts": [
317
- "one colour, or several for a multi-stripe pattern",
338
+ "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()",
318
339
  "null for a translucent black"
319
340
  ]
320
341
  },
@@ -329,14 +350,16 @@
329
350
  "name": "$rotation",
330
351
  "default": "-45deg",
331
352
  "accepts": [
332
- "an angle; a unitless number is treated as degrees"
353
+ "an angle in deg, grad, rad or turn, in any case, written as it is",
354
+ "a unitless number, which is treated as degrees",
355
+ "any other unit, such as px or %, is refused, because the gradient would be dropped"
333
356
  ]
334
357
  },
335
358
  {
336
359
  "name": "$image",
337
360
  "default": "null",
338
361
  "accepts": [
339
- "an image path to sit behind the stripes",
362
+ "an image path to sit behind the stripes, written unquoted unless it holds a space, a parenthesis or a quote, which are quoted",
340
363
  "var(), url(), image-set() or a gradient, written as they are rather than wrapped in url()"
341
364
  ]
342
365
  }
@@ -353,7 +376,13 @@
353
376
  "rejects": [
354
377
  ".a { @include background-stripes(red, 2em, nonsense); }",
355
378
  ".a { @include background-stripes(red, 2em, -45deg, 42); }",
356
- ".a { @include background-stripes(red, nonsense); }"
379
+ ".a { @include background-stripes(red, nonsense); }",
380
+ ".a { @include background-stripes(red, 2em, -10px); }",
381
+ ".a { @include background-stripes(red, 2em, 10%); }",
382
+ ".a { @include background-stripes(huge); }",
383
+ ".a { @include background-stripes(red \"blue\"); }",
384
+ ".a { @include background-stripes(red, 10deg); }",
385
+ ".a { @include background-stripes(red, 2); }"
357
386
  ]
358
387
  },
359
388
  {
@@ -438,7 +467,13 @@
438
467
  ],
439
468
  "rejects": [
440
469
  ".a { @include border-radius(1px, 2px, 3px); }",
441
- ".a { @include border-radius(nonsense, 5px); }"
470
+ ".a { @include border-radius(nonsense, 5px); }",
471
+ ".a { @include border-radius(-4px); }",
472
+ ".a { @include border-radius(auto); }",
473
+ ".a { @include border-radius(10deg); }",
474
+ ".a { @include border-radius(1px 2px 3px 4px 5px); }",
475
+ ".a { @include border-radius(\"top\", 1px 2px 3px); }",
476
+ ".a { @include border-radius(1px, 2px, -3px, 4px); }"
442
477
  ]
443
478
  },
444
479
  {
@@ -463,7 +498,7 @@
463
498
  "name": "$image-url",
464
499
  "default": "null",
465
500
  "accepts": [
466
- "an image path",
501
+ "an image path, as a string; a list, a number, a colour or a boolean is refused",
467
502
  "var(), url(), image-set() or a gradient, written as they are rather than wrapped in url()"
468
503
  ]
469
504
  }
@@ -475,7 +510,13 @@
475
510
  ".logo { @include brand-logo(120px, 40px, \"/img/logo.svg\"); }",
476
511
  ".logo { @include brand-logo(120px, 40px, var(--logo)); }"
477
512
  ],
478
- "rejects": []
513
+ "rejects": [
514
+ ".logo { @include brand-logo(120px, 40px, \"/img/a.svg\" \"/img/b.svg\"); }",
515
+ ".logo { @include brand-logo(120px, 40px, true); }",
516
+ ".logo { @include brand-logo(huge, 40px); }",
517
+ ".logo { @include brand-logo(120px, 10deg); }",
518
+ ".logo { @include brand-logo(\"120px\", 40px); }"
519
+ ]
479
520
  },
480
521
  {
481
522
  "name": "breakpoint",
@@ -489,7 +530,8 @@
489
530
  "only plus a breakpoint, for exactly that width",
490
531
  "min or max plus a breakpoint",
491
532
  "between plus two breakpoints",
492
- "a start and an end value"
533
+ "a start and an end value",
534
+ "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"
493
535
  ]
494
536
  }
495
537
  ],
@@ -509,7 +551,16 @@
509
551
  ".a { @include breakpoint(\"between\", \"medium\", \"large\") { color: red; } }",
510
552
  ".a { @include breakpoint() { color: red; } }",
511
553
  ".a { @include breakpoint(\"min\", var(--wide)) { color: red; } }",
512
- ".a { @include breakpoint(\"between\", var(--start) \"large\") { color: red; } }"
554
+ ".a { @include breakpoint(\"between\", var(--start) \"large\") { color: red; } }",
555
+ ".a { @include breakpoint(\"huge\") { color: red; } }",
556
+ ".a { @include breakpoint(\"min\", \"huge\") { color: red; } }",
557
+ ".a { @include breakpoint(\"min\", \"MEDIUM\") { color: red; } }",
558
+ ".a { @include breakpoint(\"between\", \"small\" \"huge\") { color: red; } }",
559
+ ".a { @include breakpoint(\"huge\", \"large\") { color: red; } }",
560
+ ".a { @include breakpoint(\"small\", \"huge\") { color: red; } }",
561
+ ".a { @include breakpoint(\"min\", 10deg) { color: red; } }",
562
+ ".a { @include breakpoint(\"max\", 50%) { color: red; } }",
563
+ ".a { @include breakpoint(\"only\", 768) { color: red; } }"
513
564
  ],
514
565
  "warns": [
515
566
  ".a { @include breakpoint(\"medium\") { color: red; } }"
@@ -582,7 +633,11 @@
582
633
  "examples": [
583
634
  ".dot { @include circle(24px); }"
584
635
  ],
585
- "rejects": []
636
+ "rejects": [
637
+ ".dot { @include circle(huge); }",
638
+ ".dot { @include circle(24); }",
639
+ ".dot { @include circle(-24px); }"
640
+ ]
586
641
  },
587
642
  {
588
643
  "name": "clearfix",
@@ -619,11 +674,17 @@
619
674
  ".grid { @include columnizer(3, 20px); }",
620
675
  ".grid { @include columnizer(3, 20px, true); }",
621
676
  ".grid { @include columnizer(3, var(--gap)); }",
622
- ".grid { @include columnizer(var(--cols)); }"
677
+ ".grid { @include columnizer(var(--cols)); }",
678
+ ".grid { @include columnizer(#{3}, 0); }"
623
679
  ],
624
680
  "rejects": [
625
681
  ".grid { @include columnizer(3, 20px, true, 9); }",
626
- ".grid { @include columnizer(3, nonsense); }"
682
+ ".grid { @include columnizer(3, nonsense); }",
683
+ ".grid { @include columnizer(3px); }",
684
+ ".grid { @include columnizer(auto); }",
685
+ ".grid { @include columnizer(3, 10deg); }",
686
+ ".grid { @include columnizer(3, 2); }",
687
+ ".grid { @include columnizer(3, red, true); }"
627
688
  ]
628
689
  },
629
690
  {
@@ -637,6 +698,7 @@
637
698
  "a size, for exactly that width, which prints a warning: write only instead",
638
699
  "two sizes for a range",
639
700
  "one of min, max, only or between followed by a size",
701
+ "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",
640
702
  "$name as a keyword, to query one named container"
641
703
  ]
642
704
  }
@@ -664,7 +726,12 @@
664
726
  ".title { @include container-query(\"min\", 400px, $name: \"none\") { color: red; } }",
665
727
  ".title { @include container-query(\"min\", 400px, $name: \"not\") { color: red; } }",
666
728
  ".title { @include container-query(\"min\", 400px, $name: \"my card\") { color: red; } }",
667
- ".title { @include container-query(\"min\", 400px, $name: \"1card\") { color: red; } }"
729
+ ".title { @include container-query(\"min\", 400px, $name: \"1card\") { color: red; } }",
730
+ ".title { @include container-query(\"huge\") { color: red; } }",
731
+ ".title { @include container-query(\"min\", \"huge\") { color: red; } }",
732
+ ".title { @include container-query(\"max\", 400) { color: red; } }",
733
+ ".title { @include container-query(\"between\", 300px 10deg) { color: red; } }",
734
+ ".title { @include container-query(300px, 50%) { color: red; } }"
668
735
  ],
669
736
  "warns": [
670
737
  ".title { @include container-query(400px) { color: red; } }"
@@ -754,7 +821,10 @@
754
821
  "name": "$display",
755
822
  "default": "inline-block",
756
823
  "accepts": [
757
- "a display value"
824
+ "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",
825
+ "a vendor keyword such as -webkit-box, a CSS-wide keyword, or var()",
826
+ "null to leave display out",
827
+ "a quoted value is written without its quotes; a combination the browser drops, such as block inline, is refused"
758
828
  ]
759
829
  }
760
830
  ],
@@ -765,7 +835,16 @@
765
835
  ".a { @include ellipsis; }",
766
836
  ".a { @include ellipsis(200px); }"
767
837
  ],
768
- "rejects": []
838
+ "rejects": [
839
+ ".a { @include ellipsis(100%, huge); }",
840
+ ".a { @include ellipsis(100%, block inline); }",
841
+ ".a { @include ellipsis(100%, inline-block flow); }",
842
+ ".a { @include ellipsis(100%, 10px); }",
843
+ ".a { @include ellipsis(huge); }",
844
+ ".a { @include ellipsis(auto); }",
845
+ ".a { @include ellipsis(-10px); }",
846
+ ".a { @include ellipsis(200); }"
847
+ ]
769
848
  },
770
849
  {
771
850
  "name": "escape-to-parent",
@@ -797,23 +876,35 @@
797
876
  "name": "$params",
798
877
  "variadic": true,
799
878
  "accepts": [
800
- "a positive or negative index",
879
+ "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",
880
+ "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",
801
881
  "first, last, odd or even",
802
882
  "a selector such as .foo",
803
- "several indexes"
883
+ "several indexes, all of them numbers"
804
884
  ]
805
885
  }
806
886
  ],
807
887
  "file": "scss/library/_except.scss",
808
888
  "signature": "except($params...)",
809
889
  "summary": "Selects every sibling except the ones named.",
890
+ "caveats": [
891
+ "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`."
892
+ ],
810
893
  "examples": [
811
894
  ".a { @include except(\"first\") { margin: 0; } }",
812
895
  ".a { @include except(2) { margin: 0; } }",
813
- ".a { @include except(1, 3) { margin: 0; } }"
896
+ ".a { @include except(1, 3) { margin: 0; } }",
897
+ ".a { @include except(3n) { margin: 0; } }"
814
898
  ],
815
899
  "rejects": [
816
- ".a { @include except(#ff0000) { margin: 0; } }"
900
+ ".a { @include except(#ff0000) { margin: 0; } }",
901
+ ".a { @include except(10deg) { margin: 0; } }",
902
+ ".a { @include except(-10px) { margin: 0; } }",
903
+ ".a { @include except(1.5) { margin: 0; } }",
904
+ ".a { @include except(0) { margin: 0; } }",
905
+ ".a { @include except(0n) { margin: 0; } }",
906
+ ".a { @include except(1, 10deg) { margin: 0; } }",
907
+ ".a { @include except(2, \"first\") { margin: 0; } }"
817
908
  ]
818
909
  },
819
910
  {
@@ -838,7 +929,8 @@
838
929
  "name": "$color",
839
930
  "default": "currentColor",
840
931
  "accepts": [
841
- "any CSS colour, including currentColor and var()"
932
+ "a colour, currentColor, a system colour such as Highlight, or a function such as var() or color-mix()",
933
+ "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"
842
934
  ]
843
935
  }
844
936
  ],
@@ -850,7 +942,16 @@
850
942
  ".card-link { @include focus-ring(3px, 4px, var(--focus)); }"
851
943
  ],
852
944
  "rejects": [
853
- "@include focus-ring;"
945
+ "@include focus-ring;",
946
+ ".button { @include focus-ring(2px, 2px, huge); }",
947
+ ".button { @include focus-ring(2px, 2px, \"red\"); }",
948
+ ".button { @include focus-ring(2px, 2px, 10px); }",
949
+ ".button { @include focus-ring(2px, 2px, inherit); }",
950
+ ".button { @include focus-ring(huge); }",
951
+ ".button { @include focus-ring(5%); }",
952
+ ".button { @include focus-ring(-2px); }",
953
+ ".button { @include focus-ring(2px, 5%); }",
954
+ ".button { @include focus-ring(2px, thin); }"
854
955
  ]
855
956
  },
856
957
  {
@@ -875,14 +976,17 @@
875
976
  "name": "$font-style",
876
977
  "default": "normal",
877
978
  "accepts": [
878
- "normal, italic or oblique, or a weight number"
979
+ "normal, italic, oblique or auto, or oblique with one or two angles from -90deg to 90deg",
980
+ "a number from 1 to 1000, which is read as the weight"
879
981
  ]
880
982
  },
881
983
  {
882
984
  "name": "$font-weight",
883
985
  "default": "400",
884
986
  "accepts": [
885
- "a weight"
987
+ "normal, bold, auto, or a number from 1 to 1000",
988
+ "two numbers for a variable font's range, such as 100 900",
989
+ "bolder, lighter and the CSS-wide keywords are refused, because a @font-face rule drops them"
886
990
  ]
887
991
  },
888
992
  {
@@ -908,7 +1012,9 @@
908
1012
  "@include font-face(\"Inter\", \"/fonts/inter\");",
909
1013
  "@include font-face(\"Inter\", \"/fonts/inter\", italic, 700, woff2 woff);",
910
1014
  "@include font-face(\"Readex Pro\", \"/fonts/readex\", $font-weight: 160 700, $file-formats: woff2, $font-display: swap);",
911
- "@include font-face(\"Inter\", \"/fonts/inter\", \"italic\", $font-weight: \"bold\", $file-formats: woff2);"
1015
+ "@include font-face(\"Inter\", \"/fonts/inter\", \"italic\", $font-weight: \"bold\", $file-formats: woff2);",
1016
+ "@include font-face(\"Inter\", \"/fonts/inter\", oblique 10deg 20deg, $font-weight: 450.5, $file-formats: woff2);",
1017
+ "@include font-face(\"Inter\", \"/fonts/inter\", auto, \"100 900\", $file-formats: woff2);"
912
1018
  ],
913
1019
  "rejects": [
914
1020
  ".a { @include font-face(\"Inter\", \"/fonts/inter\"); }",
@@ -926,7 +1032,14 @@
926
1032
  "@include font-face(\"Inter\", \"/fonts/inter\", $font-weight: 100 var(--max-weight), $file-formats: woff2);",
927
1033
  "@include font-face(sans-serif, \"/fonts/inter\", $file-formats: woff2);",
928
1034
  "@include font-face(inherit, \"/fonts/inter\", $file-formats: woff2);",
929
- "@include font-face(env(--font-family), \"/fonts/inter\", $file-formats: woff2);"
1035
+ "@include font-face(env(--font-family), \"/fonts/inter\", $file-formats: woff2);",
1036
+ "@include font-face(\"Inter\", \"/fonts/inter\", huge, $file-formats: woff2);",
1037
+ "@include font-face(\"Inter\", \"/fonts/inter\", oblique 100deg, $file-formats: woff2);",
1038
+ "@include font-face(\"Inter\", \"/fonts/inter\", inherit, $file-formats: woff2);",
1039
+ "@include font-face(\"Inter\", \"/fonts/inter\", $font-weight: huge, $file-formats: woff2);",
1040
+ "@include font-face(\"Inter\", \"/fonts/inter\", $font-weight: bolder, $file-formats: woff2);",
1041
+ "@include font-face(\"Inter\", \"/fonts/inter\", $font-weight: 0, $file-formats: woff2);",
1042
+ "@include font-face(\"Inter\", \"/fonts/inter\", $font-weight: 100 200 300, $file-formats: woff2);"
930
1043
  ]
931
1044
  },
932
1045
  {
@@ -1001,7 +1114,10 @@
1001
1114
  "name": "$colors",
1002
1115
  "required": true,
1003
1116
  "accepts": [
1004
- "two or more colours"
1117
+ "one or more colour stops: a colour, or a colour with one or two positions, such as (red 0 10%) (blue 10% 100%)",
1118
+ "a position on its own between two colours, as a hint, such as (red, 30%, blue)",
1119
+ "var() for a stop or the whole list",
1120
+ "a word that is not a colour, a position first or last, two positions in a row, three positions in a stop and null are refused, because the gradient would be dropped"
1005
1121
  ]
1006
1122
  }
1007
1123
  ],
@@ -1014,7 +1130,14 @@
1014
1130
  ],
1015
1131
  "rejects": [
1016
1132
  ".a { @include linear-gradient(sideways, (red, blue)); }",
1017
- ".a { @include linear-gradient(true, (red, blue)); }"
1133
+ ".a { @include linear-gradient(true, (red, blue)); }",
1134
+ ".a { @include linear-gradient(\"top\", (huge, blue)); }",
1135
+ ".a { @include linear-gradient(\"top\", (inherit, blue)); }",
1136
+ ".a { @include linear-gradient(\"top\", (red, 10%)); }",
1137
+ ".a { @include linear-gradient(\"top\", (10%, red, blue)); }",
1138
+ ".a { @include linear-gradient(\"top\", (red, 30%, 40%, blue)); }",
1139
+ ".a { @include linear-gradient(\"top\", (red 10% 20% 30%, blue)); }",
1140
+ ".a { @include linear-gradient(\"top\", null); }"
1018
1141
  ]
1019
1142
  },
1020
1143
  {
@@ -1070,23 +1193,35 @@
1070
1193
  "name": "$params",
1071
1194
  "variadic": true,
1072
1195
  "accepts": [
1073
- "a positive or negative index",
1196
+ "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",
1197
+ "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",
1074
1198
  "first, last, odd or even",
1075
1199
  "a selector such as .foo",
1076
- "several indexes"
1200
+ "several indexes, all of them numbers"
1077
1201
  ]
1078
1202
  }
1079
1203
  ],
1080
1204
  "file": "scss/library/_only.scss",
1081
1205
  "signature": "only($params...)",
1082
1206
  "summary": "Selects only the siblings named.",
1207
+ "caveats": [
1208
+ "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`."
1209
+ ],
1083
1210
  "examples": [
1084
1211
  ".a { @include only(\"first\") { margin: 0; } }",
1085
1212
  ".a { @include only(-1) { margin: 0; } }",
1086
- ".a { @include only(1, 3) { margin: 0; } }"
1213
+ ".a { @include only(1, 3) { margin: 0; } }",
1214
+ ".a { @include only(3n) { margin: 0; } }"
1087
1215
  ],
1088
1216
  "rejects": [
1089
- ".a { @include only(#ff0000) { margin: 0; } }"
1217
+ ".a { @include only(#ff0000) { margin: 0; } }",
1218
+ ".a { @include only(10deg) { margin: 0; } }",
1219
+ ".a { @include only(-10px) { margin: 0; } }",
1220
+ ".a { @include only(1.5) { margin: 0; } }",
1221
+ ".a { @include only(0) { margin: 0; } }",
1222
+ ".a { @include only(0n) { margin: 0; } }",
1223
+ ".a { @include only(1, 10deg) { margin: 0; } }",
1224
+ ".a { @include only(2, \"first\") { margin: 0; } }"
1090
1225
  ]
1091
1226
  },
1092
1227
  {
@@ -1121,7 +1256,10 @@
1121
1256
  "name": "$position",
1122
1257
  "default": "absolute",
1123
1258
  "accepts": [
1124
- "any CSS position value"
1259
+ "static, relative, absolute, fixed or sticky, in any case, or a vendor keyword such as -webkit-sticky",
1260
+ "a CSS-wide keyword or var()",
1261
+ "null to leave position out",
1262
+ "a quoted keyword is written without its quotes; any other word is refused, because the declaration would be dropped"
1125
1263
  ]
1126
1264
  },
1127
1265
  {
@@ -1131,18 +1269,42 @@
1131
1269
  "one to four lengths in shorthand order, or auto/inherit/initial/0",
1132
1270
  "null in any position to leave that edge out"
1133
1271
  ]
1272
+ },
1273
+ {
1274
+ "name": "$logical",
1275
+ "default": "false",
1276
+ "accepts": [
1277
+ "false, the default, for top, right, bottom and left",
1278
+ "null, read as false",
1279
+ "true for inset-block-start, inset-inline-end, inset-block-end and inset-inline-start, which follow the writing direction"
1280
+ ]
1134
1281
  }
1135
1282
  ],
1136
1283
  "file": "scss/library/_position.scss",
1137
- "signature": "position($position: absolute, $offsets: 0)",
1284
+ "signature": "position($position: absolute, $offsets: 0, $logical: false)",
1138
1285
  "summary": "Sets position and offsets in one call, using shorthand order.",
1139
1286
  "examples": [
1140
1287
  ".a { @include position(absolute, 0); }",
1141
1288
  ".a { @include position(fixed, 0 10px); }",
1142
1289
  ".a { @include position(absolute, null 16px 16px 16px); }",
1143
- ".a { @include position(absolute, 0 null null 0); }"
1290
+ ".a { @include position(absolute, 0 null null 0); }",
1291
+ ".badge { @include position(absolute, 0 auto auto 1rem, $logical: true); }",
1292
+ ".a { @include position(absolute, 0, $logical: null); }",
1293
+ ".a { @include position(absolute, #{16}px AUTO revert-layer); }",
1294
+ ".tip { @include position(absolute, anchor(bottom) null null anchor(left)); }"
1144
1295
  ],
1145
- "rejects": []
1296
+ "rejects": [
1297
+ ".badge { @include position(absolute, 0, $logical: yes); }",
1298
+ ".a { @include position(huge, 0); }",
1299
+ ".a { @include position(10px, 0); }",
1300
+ ".a { @include position(\"absolute fixed\", 0); }",
1301
+ ".a { @include position(absolute, 5); }",
1302
+ ".a { @include position(absolute, 0 10deg); }",
1303
+ ".a { @include position(absolute, none); }",
1304
+ ".a { @include position(absolute, red); }",
1305
+ ".a { @include position(absolute, \"10px\"); }",
1306
+ ".a { @include position(absolute, url(a.png)); }"
1307
+ ]
1146
1308
  },
1147
1309
  {
1148
1310
  "name": "radial-gradient",
@@ -1152,7 +1314,9 @@
1152
1314
  "name": "$shape",
1153
1315
  "required": true,
1154
1316
  "accepts": [
1155
- "circle or ellipse"
1317
+ "circle or ellipse",
1318
+ "with a size as a string: an extent keyword such as \"circle closest-side\", one length for a circle, or two lengths or percentages for an ellipse",
1319
+ "var() or calc()"
1156
1320
  ]
1157
1321
  },
1158
1322
  {
@@ -1160,14 +1324,17 @@
1160
1324
  "required": true,
1161
1325
  "accepts": [
1162
1326
  "a position name such as center or top-left",
1163
- "a raw CSS position"
1327
+ "an extent keyword such as closest-side",
1328
+ "at followed by a position, as a string, such as \"at 30% 40%\" or \"at left 10px top 20px\", optionally after a size",
1329
+ "a word outside these, such as inherit, is refused, because the whole gradient would be dropped"
1164
1330
  ]
1165
1331
  },
1166
1332
  {
1167
1333
  "name": "$colors",
1168
1334
  "required": true,
1169
1335
  "accepts": [
1170
- "two or more colours"
1336
+ "one or more colour stops, in the same forms as linear-gradient: a colour with up to two positions, a position between two colours, or var()",
1337
+ "a stop the browser drops is refused, because the whole gradient would be dropped"
1171
1338
  ]
1172
1339
  }
1173
1340
  ],
@@ -1179,7 +1346,14 @@
1179
1346
  ],
1180
1347
  "rejects": [
1181
1348
  ".a { @include radial-gradient(42, \"center\", (red, blue)); }",
1182
- ".a { @include radial-gradient(circle, 42, (red, blue)); }"
1349
+ ".a { @include radial-gradient(circle, 42, (red, blue)); }",
1350
+ ".a { @include radial-gradient(huge, \"center\", (red, blue)); }",
1351
+ ".a { @include radial-gradient(\"circle 10%\", \"center\", (red, blue)); }",
1352
+ ".a { @include radial-gradient(circle, huge, (red, blue)); }",
1353
+ ".a { @include radial-gradient(circle, \"at huge\", (red, blue)); }",
1354
+ ".a { @include radial-gradient(circle, inherit, (red, blue)); }",
1355
+ ".a { @include radial-gradient(circle, \"center\", (huge, blue)); }",
1356
+ ".a { @include radial-gradient(circle, \"center\", (red, blue, 90%)); }"
1183
1357
  ]
1184
1358
  },
1185
1359
  {
@@ -1214,7 +1388,10 @@
1214
1388
  ],
1215
1389
  "rejects": [
1216
1390
  ".a { @include remove(a, b, c); }",
1217
- ".a { @include remove(\"max\", var(--narrow)); }"
1391
+ ".a { @include remove(\"max\", var(--narrow)); }",
1392
+ ".a { @include remove(\"huge\"); }",
1393
+ ".a { @include remove(\"min\", \"huge\"); }",
1394
+ ".a { @include remove(\"huge\", \"large\"); }"
1218
1395
  ],
1219
1396
  "warns": [
1220
1397
  ".a { @include remove(\"medium\"); }"
@@ -1254,14 +1431,16 @@
1254
1431
  "name": "$direction",
1255
1432
  "default": "both",
1256
1433
  "accepts": [
1257
- "a CSS resize value such as both, horizontal, vertical or none"
1434
+ "none, both, horizontal, vertical, block, inline or auto, in any case",
1435
+ "a CSS-wide keyword, var(), or null to leave resize out; a quoted keyword is written without its quotes"
1258
1436
  ]
1259
1437
  },
1260
1438
  {
1261
1439
  "name": "$overflow",
1262
1440
  "default": "auto",
1263
1441
  "accepts": [
1264
- "a CSS overflow value"
1442
+ "one or two of visible, hidden, clip, scroll, auto and overlay, such as hidden auto",
1443
+ "a CSS-wide keyword on its own, var(), or null to leave overflow out; a quoted value is written without its quotes"
1265
1444
  ]
1266
1445
  }
1267
1446
  ],
@@ -1272,7 +1451,12 @@
1272
1451
  ".a { @include resizable; }",
1273
1452
  ".a { @include resizable(vertical, scroll); }"
1274
1453
  ],
1275
- "rejects": []
1454
+ "rejects": [
1455
+ ".a { @include resizable(huge); }",
1456
+ ".a { @include resizable(both, huge); }",
1457
+ ".a { @include resizable(both, hidden hidden hidden); }",
1458
+ ".a { @include resizable(both, inherit auto); }"
1459
+ ]
1276
1460
  },
1277
1461
  {
1278
1462
  "name": "responsive-image",
@@ -1308,7 +1492,9 @@
1308
1492
  ],
1309
1493
  "rejects": [
1310
1494
  ".a { @include scissors(5px 10px); }",
1311
- ".a { @include scissors(nonsense); }"
1495
+ ".a { @include scissors(nonsense); }",
1496
+ ".a { @include scissors(10deg); }",
1497
+ ".a { @include scissors(4px 8px 12px 1x); }"
1312
1498
  ]
1313
1499
  },
1314
1500
  {
@@ -1320,7 +1506,7 @@
1320
1506
  "required": true,
1321
1507
  "accepts": [
1322
1508
  "1x, 2x or 3x",
1323
- "a raw resolution such as 120dpi"
1509
+ "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"
1324
1510
  ]
1325
1511
  }
1326
1512
  ],
@@ -1331,7 +1517,11 @@
1331
1517
  ".a { @include screen-agent(\"2x\") { background-image: url(\"/img/a@2x.png\"); } }"
1332
1518
  ],
1333
1519
  "rejects": [
1334
- ".a { @include screen-agent(var(--density)) { color: red; } }"
1520
+ ".a { @include screen-agent(var(--density)) { color: red; } }",
1521
+ ".a { @include screen-agent(\"huge\") { color: red; } }",
1522
+ ".a { @include screen-agent(2) { color: red; } }",
1523
+ ".a { @include screen-agent(10px) { color: red; } }",
1524
+ ".a { @include screen-agent(-1dppx) { color: red; } }"
1335
1525
  ]
1336
1526
  },
1337
1527
  {
@@ -1360,7 +1550,13 @@
1360
1550
  ".a { @include sizer(40px); }",
1361
1551
  ".a { @include sizer(120px, 40px); }"
1362
1552
  ],
1363
- "rejects": []
1553
+ "rejects": [
1554
+ ".a { @include sizer(huge); }",
1555
+ ".a { @include sizer(40); }",
1556
+ ".a { @include sizer(120px, 10deg); }",
1557
+ ".a { @include sizer(-40px); }",
1558
+ ".a { @include sizer(\"40px\"); }"
1559
+ ]
1364
1560
  },
1365
1561
  {
1366
1562
  "name": "smartphone",
@@ -1405,7 +1601,7 @@
1405
1601
  "accepts": [
1406
1602
  "an image path ending in .png, .jpg or .svg",
1407
1603
  "a background position",
1408
- "both, image first"
1604
+ "both, image first, where the image is one path as a string"
1409
1605
  ]
1410
1606
  }
1411
1607
  ],
@@ -1418,7 +1614,14 @@
1418
1614
  ".icon { @include sprite(0 -40px); }"
1419
1615
  ],
1420
1616
  "rejects": [
1421
- ".icon { @include sprite(\"/img/sprite.txt\"); }"
1617
+ ".icon { @include sprite(\"/img/sprite.txt\"); }",
1618
+ ".icon { @include sprite(\"/img/a.png\" \"/img/b.png\", 0 -40px); }",
1619
+ ".icon { @include sprite(42, 0 -40px); }",
1620
+ ".icon { @include sprite(0 red); }",
1621
+ ".icon { @include sprite(\"/img/sprite.png\", 10deg); }",
1622
+ ".icon { @include sprite(\"/img/sprite.png\", 1); }",
1623
+ ".icon { @include sprite(\"/img/sprite.png\", 10px 20px 30px 40px); }",
1624
+ ".icon { @include sprite(\"/img/sprite.png\", auto); }"
1422
1625
  ]
1423
1626
  },
1424
1627
  {
@@ -1493,7 +1696,8 @@
1493
1696
  "name": "$colors",
1494
1697
  "required": true,
1495
1698
  "accepts": [
1496
- "two or more colours"
1699
+ "one or more colour stops, in the same forms as linear-gradient: a colour with up to two positions, a position between two colours, or var()",
1700
+ "a stop the browser drops is refused, because the gradient and the transparent text would go with it"
1497
1701
  ]
1498
1702
  }
1499
1703
  ],
@@ -1504,7 +1708,9 @@
1504
1708
  ".a { @include text-gradient(\"top\", (red, blue)); }"
1505
1709
  ],
1506
1710
  "rejects": [
1507
- ".a { @include text-gradient(sideways, (red, blue)); }"
1711
+ ".a { @include text-gradient(sideways, (red, blue)); }",
1712
+ ".a { @include text-gradient(\"top\", (huge, blue)); }",
1713
+ ".a { @include text-gradient(\"top\", (\"red\", blue)); }"
1508
1714
  ]
1509
1715
  },
1510
1716
  {
@@ -1515,7 +1721,7 @@
1515
1721
  "name": "$image",
1516
1722
  "default": "null",
1517
1723
  "accepts": [
1518
- "an image path",
1724
+ "an image path, as a string; a list, a number, a colour or a boolean is refused",
1519
1725
  "var(), url(), image-set() or a gradient, written as they are rather than wrapped in url()"
1520
1726
  ]
1521
1727
  }
@@ -1527,7 +1733,10 @@
1527
1733
  ".a { @include text-image(\"/img/t.png\"); }",
1528
1734
  ".a { @include text-image(var(--texture)); }"
1529
1735
  ],
1530
- "rejects": []
1736
+ "rejects": [
1737
+ ".a { @include text-image(16 9); }",
1738
+ ".a { @include text-image(#ff0000); }"
1739
+ ]
1531
1740
  },
1532
1741
  {
1533
1742
  "name": "text-selection",
@@ -1584,14 +1793,16 @@
1584
1793
  "name": "$fallback-color",
1585
1794
  "default": "black",
1586
1795
  "accepts": [
1587
- "a colour for browsers without text-stroke"
1796
+ "a colour for browsers without text-stroke",
1797
+ "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"
1588
1798
  ]
1589
1799
  },
1590
1800
  {
1591
1801
  "name": "$color",
1592
1802
  "default": "transparent",
1593
1803
  "accepts": [
1594
- "the text fill colour"
1804
+ "the text fill colour",
1805
+ "a word that is not a colour, a quoted colour, a length or two colours are refused"
1595
1806
  ]
1596
1807
  },
1597
1808
  {
@@ -1616,7 +1827,16 @@
1616
1827
  ".a { @include text-stroke; }",
1617
1828
  ".a { @include text-stroke(black, transparent, red, 2px); }"
1618
1829
  ],
1619
- "rejects": []
1830
+ "rejects": [
1831
+ ".a { @include text-stroke(huge); }",
1832
+ ".a { @include text-stroke(black, \"red\"); }",
1833
+ ".a { @include text-stroke(black, transparent, 10px); }",
1834
+ ".a { @include text-stroke(black, transparent, red blue); }",
1835
+ ".a { @include text-stroke(black, transparent, red, huge); }",
1836
+ ".a { @include text-stroke(black, transparent, red, 5%); }",
1837
+ ".a { @include text-stroke(black, transparent, red, -1px); }",
1838
+ ".a { @include text-stroke(black, transparent, red, 2); }"
1839
+ ]
1620
1840
  },
1621
1841
  {
1622
1842
  "name": "tokens",
@@ -1685,7 +1905,9 @@
1685
1905
  "accepts": [
1686
1906
  "a Sass colour, such as red, #333 or oklch(70% 0.1 200)",
1687
1907
  "currentColor",
1688
- "var(), color-mix() or light-dark(), which CSS resolves"
1908
+ "a system colour such as Canvas",
1909
+ "var(), color-mix(), light-dark(), contrast-color() or rgb(from ...), which CSS resolves",
1910
+ "a CSS-wide keyword is refused, because it is invalid inside the border-color shorthand"
1689
1911
  ]
1690
1912
  },
1691
1913
  {
@@ -1714,7 +1936,13 @@
1714
1936
  ".caret { @include triangle(sideways); }",
1715
1937
  ".caret { @include triangle(\"top\", notacolor); }",
1716
1938
  ".caret { @include triangle(\"top\", url(a.png)); }",
1717
- ".caret { @include triangle(\"top\", red, nonsense); }"
1939
+ ".caret { @include triangle(\"top\", red, nonsense); }",
1940
+ ".caret { @include triangle(\"top\", -webkit-fill-available); }",
1941
+ ".caret { @include triangle(\"top\", red, 5%); }",
1942
+ ".caret { @include triangle(\"top\", red, -10px); }",
1943
+ ".caret { @include triangle(\"top\", red, thin); }",
1944
+ ".caret { @include triangle(\"top\", red, 10); }",
1945
+ ".caret { @include triangle(\"top\", red, 10px 10deg); }"
1718
1946
  ]
1719
1947
  },
1720
1948
  {
@@ -2233,17 +2461,21 @@
2233
2461
  "name": "$value",
2234
2462
  "required": true,
2235
2463
  "accepts": [
2236
- "a key from $map-for-breakpoints, or a raw length"
2464
+ "a key from $map-for-breakpoints",
2465
+ "a length, a percentage or a CSS function such as var() or min(), returned as it is"
2237
2466
  ]
2238
2467
  }
2239
2468
  ],
2240
2469
  "file": "scss/utilities/_validate-breakpoint.scss",
2241
2470
  "signature": "validateBreakpoint($value)",
2242
- "summary": "Resolves a breakpoint name to its width, passing other values through.",
2471
+ "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.",
2243
2472
  "examples": [
2244
2473
  ".a { width: validateBreakpoint(\"medium\"); }"
2245
2474
  ],
2246
- "rejects": []
2475
+ "rejects": [
2476
+ ".a { width: validateBreakpoint(\"huge\"); }",
2477
+ ".a { width: validateBreakpoint(\"small\" \"medium\"); }"
2478
+ ]
2247
2479
  },
2248
2480
  {
2249
2481
  "name": "validateLength",