gerillass 0.0.6 → 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.
- checksums.yaml +4 -4
- data/LICENSE.md +13 -0
- data/README.md +328 -0
- data/SKILL.md +283 -0
- data/gerillass.json +2551 -0
- data/lib/gerillass/engine.rb +55 -0
- data/lib/gerillass/jekyll.rb +13 -0
- data/lib/gerillass.rb +26 -0
- data/scss/_gerillass.scss +15 -0
- data/scss/internal/_color-problem.scss +99 -0
- data/scss/internal/_color-stops-problem.scss +94 -0
- data/scss/internal/_condition-width.scss +22 -0
- data/scss/internal/_custom-property-in.scss +25 -0
- data/scss/internal/_image-value.scss +68 -0
- data/scss/internal/_is-condition-value.scss +94 -0
- data/scss/internal/_is-css-function.scss +21 -0
- data/scss/internal/_is-size.scss +22 -0
- data/scss/internal/_keyword-value.scss +76 -0
- data/scss/internal/_length-problem.scss +127 -0
- data/scss/internal/_sibling-index.scss +51 -0
- data/scss/internal/_words.scss +35 -0
- data/scss/library/_adaptive.scss +31 -0
- data/scss/library/_after.scss +28 -0
- data/scss/library/_all-buttons.scss +21 -0
- data/scss/library/_all-text-inputs.scss +21 -0
- data/{core → scss}/library/_antialias.scss +5 -1
- data/scss/library/_aspect-ratio.scss +27 -0
- data/scss/library/_background-dots.scss +103 -0
- data/scss/library/_background-image.scss +113 -0
- data/scss/library/_background-stripes.scss +99 -0
- data/scss/library/_before.scss +28 -0
- data/scss/library/_border-box.scss +30 -0
- data/scss/library/_border-radius.scss +164 -0
- data/scss/library/_brand-logo.scss +33 -0
- data/scss/library/_breakpoint.scss +96 -0
- data/scss/library/_breakpointer.scss +40 -0
- data/scss/library/_center.scss +19 -0
- data/scss/library/_circle.scss +15 -0
- data/{core → scss}/library/_clearfix.scss +1 -1
- data/scss/library/_columnizer.scss +125 -0
- data/scss/library/_container-query.scss +119 -0
- data/scss/library/_container.scss +72 -0
- data/scss/library/_counter.scss +59 -0
- data/scss/library/_ellipsis.scss +87 -0
- data/scss/library/_escape-to-parent.scss +12 -0
- data/scss/library/_except.scss +71 -0
- data/scss/library/_focus-ring.scss +63 -0
- data/scss/library/_font-face.scss +240 -0
- data/scss/library/_hide.scss +25 -0
- data/scss/library/_index.scss +58 -0
- data/scss/library/_line-clamp.scss +38 -0
- data/scss/library/_linear-gradient.scss +33 -0
- data/scss/library/_loadify.scss +62 -0
- data/scss/library/_motion-safe.scss +28 -0
- data/scss/library/_only.scss +73 -0
- data/scss/library/_placeholder-shown.scss +7 -0
- data/scss/library/_placeholder.scss +19 -0
- data/scss/library/_position.scss +72 -0
- data/scss/library/_radial-gradient.scss +184 -0
- data/scss/library/_remove.scss +40 -0
- data/scss/library/_reset-css.scss +57 -0
- data/scss/library/_reset-figure.scss +10 -0
- data/scss/library/_resizable.scss +34 -0
- data/scss/library/_responsive-image.scss +6 -0
- data/scss/library/_scissors.scss +34 -0
- data/scss/library/_screen-agent.scss +34 -0
- data/scss/library/_sizer.scss +15 -0
- data/scss/library/_smartphone.scss +29 -0
- data/scss/library/_sprite.scss +100 -0
- data/scss/library/_stretched-link.scss +21 -0
- data/scss/library/_tablet.scss +29 -0
- data/scss/library/_text-gradient.scss +38 -0
- data/scss/library/_text-image.scss +15 -0
- data/scss/library/_text-selection.scss +22 -0
- data/scss/library/_text-shadow.scss +145 -0
- data/scss/library/_text-stroke.scss +43 -0
- data/scss/library/_tokens.scss +111 -0
- data/scss/library/_triangle.scss +115 -0
- data/scss/lists/_index.scss +8 -0
- data/scss/lists/_list-of-anchor-pseudo-classes.scss +9 -0
- data/scss/lists/_list-of-buttons.scss +8 -0
- data/scss/lists/_list-of-counter-styles.scss +59 -0
- data/scss/lists/_list-of-directions.scss +12 -0
- data/scss/lists/_list-of-length-units.scss +23 -0
- data/scss/lists/_list-of-text-inputs.scss +20 -0
- data/scss/maps/_index.scss +8 -0
- data/scss/maps/_map-for-breakpoints.scss +9 -0
- data/scss/maps/_map-for-directions.scss +12 -0
- data/scss/maps/_map-for-font-formats.scss +9 -0
- data/scss/maps/_map-for-positions.scss +13 -0
- data/scss/maps/_map-for-smartphones.scss +72 -0
- data/scss/maps/_map-for-tablets.scss +32 -0
- data/scss/utilities/_clear-unit.scss +11 -0
- data/scss/utilities/_clear-whitespace.scss +15 -0
- data/scss/utilities/_convert-to-em.scss +16 -0
- data/scss/utilities/_convert-to-number.scss +45 -0
- data/scss/utilities/_fill-nulls.scss +18 -0
- data/scss/utilities/_fluid.scss +76 -0
- data/scss/utilities/_font-sizer.scss +19 -0
- data/scss/utilities/_font-source.scss +23 -0
- data/scss/utilities/_index.scss +25 -0
- data/scss/utilities/_is-color.scss +16 -0
- data/scss/utilities/_is-gutter.scss +24 -0
- data/scss/utilities/_is-number.scss +11 -0
- data/scss/utilities/_is-time.scss +14 -0
- data/scss/utilities/_map-deep-get.scss +10 -0
- data/scss/utilities/_pixelify.scss +20 -0
- data/scss/utilities/_pseudo-selector.scss +12 -0
- data/scss/utilities/_remify.scss +16 -0
- data/scss/utilities/_shade.scss +10 -0
- data/scss/utilities/_shorthand-property.scss +17 -0
- data/scss/utilities/_tint.scss +10 -0
- data/scss/utilities/_validate-breakpoint.scss +41 -0
- data/scss/utilities/_validate-length.scss +37 -0
- data/scss/utilities/_validate-ratio.scss +77 -0
- data/scss/utilities/_validate-scissors.scss +34 -0
- metadata +130 -46
- data/core/_gerillass.scss +0 -4
- data/core/library/_before.scss +0 -18
- data/core/library/_border-box.scss +0 -26
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "sass:map";
|
|
5
|
+
@use "sass:math";
|
|
6
|
+
@use "sass:meta";
|
|
7
|
+
@use "sass:string";
|
|
8
|
+
@use "../maps/map-for-font-formats" as *;
|
|
9
|
+
@use "../utilities/font-source" as *;
|
|
10
|
+
@use "../internal/is-condition-value" as *;
|
|
11
|
+
@use "../internal/words" as *;
|
|
12
|
+
|
|
13
|
+
// What a @font-face rule keeps in `font-style` and `font-weight`, measured in
|
|
14
|
+
// Chrome 152 by inserting the rule and reading the descriptor back, in any
|
|
15
|
+
// case. font-style kept normal, italic, auto, oblique, and oblique with one or
|
|
16
|
+
// two angles from -90deg to 90deg (`oblique 10deg 20deg`, `oblique 0.2rad`),
|
|
17
|
+
// and dropped a CSS-wide keyword, `oblique 100deg`, an angle without a unit
|
|
18
|
+
// and a weight such as `400`. font-weight kept normal, bold, auto, a number
|
|
19
|
+
// from 1 to 1000 (`450`, `400.5`, `calc(400 + 100)`) and two numbers as a range
|
|
20
|
+
// in either order, and dropped bolder and lighter, a CSS-wide keyword, 0, 1001,
|
|
21
|
+
// three numbers, and a keyword beside a number or another keyword.
|
|
22
|
+
//
|
|
23
|
+
// A quoted value is split on its spaces and checked word by word, but Sass
|
|
24
|
+
// cannot turn the text of a number into one, so a quoted number is checked for
|
|
25
|
+
// its shape and not its range: "1001" and "oblique 100deg" are let through.
|
|
26
|
+
|
|
27
|
+
// A quoted or unquoted number, without a unit, for a weight.
|
|
28
|
+
@function -is-weight-number($word) {
|
|
29
|
+
@if meta.type-of($word) == "number" {
|
|
30
|
+
@return math.is-unitless($word) and $word >= 1 and $word <= 1000;
|
|
31
|
+
}
|
|
32
|
+
@if meta.type-of($word) != "string" {
|
|
33
|
+
@return false;
|
|
34
|
+
}
|
|
35
|
+
$text: string.unquote($word);
|
|
36
|
+
$nonzero: false;
|
|
37
|
+
@for $i from 1 through string.length($text) {
|
|
38
|
+
$character: string.slice($text, $i, $i);
|
|
39
|
+
@if not string.index("0123456789.", $character) {
|
|
40
|
+
@return false;
|
|
41
|
+
}
|
|
42
|
+
@if string.index("123456789", $character) {
|
|
43
|
+
$nonzero: true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
@return $nonzero;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@function -weight-problem($weight) {
|
|
50
|
+
@if $weight == null or meta.type-of($weight) == "calculation" {
|
|
51
|
+
@return null;
|
|
52
|
+
}
|
|
53
|
+
$words: wordsOf($weight);
|
|
54
|
+
@if list.length($words) > 2 {
|
|
55
|
+
@return "a weight is one value, or two numbers for a range such as `100 900`";
|
|
56
|
+
}
|
|
57
|
+
@if list.length($words) == 1 {
|
|
58
|
+
$word: list.nth($words, 1);
|
|
59
|
+
@if meta.type-of($word) == "string" and list.index("normal" "bold" "auto", string.to-lower-case(string.unquote($word))) {
|
|
60
|
+
@return null;
|
|
61
|
+
}
|
|
62
|
+
@if -is-weight-number($word) {
|
|
63
|
+
@return null;
|
|
64
|
+
}
|
|
65
|
+
@return "a weight is normal, bold, auto or a number from 1 to 1000; bolder, lighter and the CSS-wide keywords are dropped";
|
|
66
|
+
}
|
|
67
|
+
@each $word in $words {
|
|
68
|
+
@if not -is-weight-number($word) {
|
|
69
|
+
@return "a range is two numbers from 1 to 1000, such as `100 900`";
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
@return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@function -style-problem($style) {
|
|
76
|
+
@if $style == null {
|
|
77
|
+
@return null;
|
|
78
|
+
}
|
|
79
|
+
$words: wordsOf($style);
|
|
80
|
+
$first: list.nth($words, 1);
|
|
81
|
+
$keyword: null;
|
|
82
|
+
@if meta.type-of($first) == "string" {
|
|
83
|
+
$keyword: string.to-lower-case(string.unquote($first));
|
|
84
|
+
}
|
|
85
|
+
@if list.index("normal" "italic" "auto", $keyword) {
|
|
86
|
+
@if list.length($words) > 1 {
|
|
87
|
+
@return "`#{$keyword}` takes nothing after it; only oblique takes angles";
|
|
88
|
+
}
|
|
89
|
+
@return null;
|
|
90
|
+
}
|
|
91
|
+
@if $keyword != "oblique" {
|
|
92
|
+
@return "a style is normal, italic, oblique or auto; the CSS-wide keywords are dropped";
|
|
93
|
+
}
|
|
94
|
+
@if list.length($words) > 3 {
|
|
95
|
+
@return "oblique takes at most two angles";
|
|
96
|
+
}
|
|
97
|
+
@for $i from 2 through list.length($words) {
|
|
98
|
+
$angle: list.nth($words, $i);
|
|
99
|
+
@if meta.type-of($angle) == "number" {
|
|
100
|
+
@if not isConditionValue($angle, "angle") {
|
|
101
|
+
@return "`#{$angle}` is not an angle; pass one such as `10deg`";
|
|
102
|
+
}
|
|
103
|
+
@if $angle < -90deg or $angle > 90deg {
|
|
104
|
+
@return "an oblique angle is between -90deg and 90deg";
|
|
105
|
+
}
|
|
106
|
+
} @else if not isConditionValue($angle, "angle") {
|
|
107
|
+
@return "`#{$angle}` is not an angle; pass one such as `10deg`";
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
@return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@mixin font-face(
|
|
114
|
+
$font-family,
|
|
115
|
+
$file-path,
|
|
116
|
+
$font-style: normal,
|
|
117
|
+
$font-weight: 400,
|
|
118
|
+
$file-formats: eot woff2 woff ttf svg,
|
|
119
|
+
$font-display: null
|
|
120
|
+
) {
|
|
121
|
+
@if & {
|
|
122
|
+
@error "You must call the mixin at the root level of your style sheet, not in the `#{&+'{'+'}'}` selector.";
|
|
123
|
+
} @else if meta.type-of($font-family) != "string" {
|
|
124
|
+
@error "`#{$font-family}` is not a valid $font-family for `font-face`. Pass the family name as a string, such as `\"Inter\"`.";
|
|
125
|
+
} @else if meta.type-of($file-path) != "string" {
|
|
126
|
+
@error "`#{$file-path}` is not a valid $file-path for `font-face`. Pass the path to the font files without an extension, as a string.";
|
|
127
|
+
} @else if string.slice(meta.inspect($file-path), 1, 1) != "\"" and string.index($file-path, "var(") {
|
|
128
|
+
// The path is written into url("..."), where var() is only text: the
|
|
129
|
+
// browser would request a file literally named var(--x).woff2.
|
|
130
|
+
@error "`#{$file-path}` is not a valid $file-path for `font-face`. A custom property cannot supply a font path, because the path is written into url() as text. Pass the path as a string.";
|
|
131
|
+
} @else if string.slice(meta.inspect($font-family), 1, 1) != "\"" and string.index($font-family, "var(") {
|
|
132
|
+
// Measured in Chrome 152, a @font-face rule dropped `font-family: var(--f)`,
|
|
133
|
+
// and a rule with no family is never used. A quoted "var(--f)" is only a
|
|
134
|
+
// name, which the browser kept, so it is left alone like a quoted path.
|
|
135
|
+
@error "`#{$font-family}` is not a valid $font-family for `font-face`. A custom property cannot supply it, because a @font-face rule drops var() in a descriptor, and without a family the font is never used. Pass the family name as a string, such as `\"Inter\"`.";
|
|
136
|
+
} @else if string.slice(meta.inspect($font-family), 1, 1) != "\"" and (list.index("serif" "sans-serif" "monospace" "cursive" "fantasy" "system-ui" "math" "inherit" "initial" "unset" "revert" "revert-layer" "default", string.to-lower-case($font-family)) or string.index($font-family, "env(") or string.index($font-family, "attr(")) {
|
|
137
|
+
// Measured in Chrome 152, a @font-face rule dropped an unquoted `serif`,
|
|
138
|
+
// `sans-serif`, `monospace`, `cursive`, `fantasy`, `system-ui`, `math`,
|
|
139
|
+
// `default` or CSS-wide keyword, in any case, and `env()` and `attr()`. The
|
|
140
|
+
// same words quoted are names and were kept, as were `emoji`, `fangsong` and
|
|
141
|
+
// the `ui-` families unquoted.
|
|
142
|
+
@error "`#{$font-family}` is not a valid $font-family for `font-face`. A @font-face rule drops a generic family, a CSS-wide keyword or a function as its family, and without a family the font is never used. Pass the family name as a quoted string, such as `\"Inter\"`.";
|
|
143
|
+
} @else {
|
|
144
|
+
|
|
145
|
+
$list: ();
|
|
146
|
+
|
|
147
|
+
// The same rule dropped `font-style: var(--s)`, `font-weight: var(--w)` and
|
|
148
|
+
// `font-weight: 100 var(--w)`, so var() is refused anywhere in either,
|
|
149
|
+
// before $font-style is reinterpreted below.
|
|
150
|
+
@if string.index(meta.inspect($font-style), "var(") {
|
|
151
|
+
@error "`#{meta.inspect($font-style)}` is not a valid $font-style for `font-face`. A custom property cannot supply it, because a @font-face rule drops var() in a descriptor. Pass the style itself, such as `italic`.";
|
|
152
|
+
}
|
|
153
|
+
@if string.index(meta.inspect($font-weight), "var(") {
|
|
154
|
+
@error "`#{meta.inspect($font-weight)}` is not a valid $font-weight for `font-face`. A custom property cannot supply it, because a @font-face rule drops var() in a descriptor. Pass the weight itself, such as `700`, or a range such as `160 700`.";
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// A number in $font-style is a weight. Only the hundreds used to be read
|
|
158
|
+
// that way, so `font-face("I", "/f/i", 450)` wrote `font-style: 450`, which
|
|
159
|
+
// a @font-face rule drops; any weight a rule keeps, 1 to 1000, is read so.
|
|
160
|
+
@if meta.type-of($font-style) == "number" and math.is-unitless($font-style) and $font-style >= 1 and $font-style <= 1000 {
|
|
161
|
+
$font-weight: $font-style;
|
|
162
|
+
$font-style: normal;
|
|
163
|
+
} @else if not
|
|
164
|
+
list.index("normal" "italic" "oblique", $font-style) and
|
|
165
|
+
meta.type-of($font-style) !=
|
|
166
|
+
"number"
|
|
167
|
+
{
|
|
168
|
+
$font-style-list: ();
|
|
169
|
+
@for $i from 1 through list.length($font-style) {
|
|
170
|
+
$font-style-list: list.append($font-style-list, list.nth($font-style, $i), comma);
|
|
171
|
+
}
|
|
172
|
+
@for $i from 1 through list.length($font-style-list) {
|
|
173
|
+
@if list.index("eot" "woff2" "woff" "ttf" "svg", list.nth($font-style-list, $i)) {
|
|
174
|
+
$file-formats: $font-style-list;
|
|
175
|
+
$font-style: normal;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Checked after the reinterpretation above, on the values that are written.
|
|
181
|
+
$problem: -style-problem($font-style);
|
|
182
|
+
@if $problem {
|
|
183
|
+
@error "`#{meta.inspect($font-style)}` is not a valid $font-style for `font-face`: #{$problem}. A @font-face rule drops the descriptor.";
|
|
184
|
+
}
|
|
185
|
+
$problem: -weight-problem($font-weight);
|
|
186
|
+
@if $problem {
|
|
187
|
+
@error "`#{meta.inspect($font-weight)}` is not a valid $font-weight for `font-face`: #{$problem}. A @font-face rule drops the descriptor.";
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// $font-display comes last so the reinterpretation of $font-style above is
|
|
191
|
+
// left alone, and it is written only when given: the browser's default is
|
|
192
|
+
// what a call without it has always had. Measured in Chrome 152, a
|
|
193
|
+
// @font-face rule drops `font-display: "swap"` and `font-display: var(--d)`
|
|
194
|
+
// without a word, so a quoted keyword is unquoted and var() is refused.
|
|
195
|
+
@if $font-display != null {
|
|
196
|
+
@if meta.type-of($font-display) == "string" and string.index($font-display, "var(") {
|
|
197
|
+
@error "`#{meta.inspect($font-display)}` is not a valid $font-display for `font-face`. A custom property cannot supply it, because a @font-face rule drops var() in a descriptor. Pass one of: auto, block, swap, fallback, optional.";
|
|
198
|
+
} @else if not list.index("auto" "block" "swap" "fallback" "optional", $font-display) {
|
|
199
|
+
@error "`#{meta.inspect($font-display)}` is not a valid $font-display for `font-face`. Pass one of: auto, block, swap, fallback, optional.";
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// fontSource returns nothing for a format it does not know, so a typo
|
|
204
|
+
// dropped that source and a list of nothing but typos dropped `src`.
|
|
205
|
+
@each $format in $file-formats {
|
|
206
|
+
@if not map.has-key($map-for-font-formats, $format) {
|
|
207
|
+
@error "`#{meta.inspect($format)}` is not a valid file format for `font-face`. Pass one or more of: #{map.keys($map-for-font-formats)}.";
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
@font-face {
|
|
212
|
+
font-family: $font-family;
|
|
213
|
+
@if list.index($file-formats, eot) {
|
|
214
|
+
src: url("#{$file-path}.eot");
|
|
215
|
+
}
|
|
216
|
+
@for $i from 1 through list.length($file-formats) {
|
|
217
|
+
$list: list.append($list, fontSource($font-family, $file-path, list.nth($file-formats, $i)), comma);
|
|
218
|
+
}
|
|
219
|
+
src: $list;
|
|
220
|
+
// A quoted keyword is written without its quotes. Measured in Chrome 152,
|
|
221
|
+
// `font-style: "italic"` and `font-weight: "bold"` were dropped, and this
|
|
222
|
+
// is what a quoted argument used to produce. The family keeps its quotes,
|
|
223
|
+
// since there they make it a name.
|
|
224
|
+
@if meta.type-of($font-style) == "string" {
|
|
225
|
+
font-style: string.unquote($font-style);
|
|
226
|
+
} @else {
|
|
227
|
+
font-style: $font-style;
|
|
228
|
+
}
|
|
229
|
+
@if meta.type-of($font-weight) == "string" {
|
|
230
|
+
font-weight: string.unquote($font-weight);
|
|
231
|
+
} @else {
|
|
232
|
+
font-weight: $font-weight;
|
|
233
|
+
}
|
|
234
|
+
@if $font-display {
|
|
235
|
+
font-display: string.unquote($font-display);
|
|
236
|
+
}
|
|
237
|
+
@content;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@mixin hide($toggle: "hide") {
|
|
4
|
+
@if $toggle == "hide" {
|
|
5
|
+
position: absolute;
|
|
6
|
+
width: 1px;
|
|
7
|
+
height: 1px;
|
|
8
|
+
padding: 0;
|
|
9
|
+
border: 0;
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
clip: rect(1px, 1px, 1px, 1px);
|
|
12
|
+
clip-path: inset(100%);
|
|
13
|
+
white-space: nowrap;
|
|
14
|
+
} @else if $toggle == "unhide" {
|
|
15
|
+
position: static;
|
|
16
|
+
width: auto;
|
|
17
|
+
height: auto;
|
|
18
|
+
overflow: visible;
|
|
19
|
+
clip: auto;
|
|
20
|
+
clip-path: none;
|
|
21
|
+
white-space: inherit;
|
|
22
|
+
} @else if not index ("hide" "unhide", $toggle) {
|
|
23
|
+
@error "#{$toggle} is not a valid value for the `$toggle` argument. The value must be either `hide` or `unhide`.";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@forward "adaptive";
|
|
4
|
+
@forward "after";
|
|
5
|
+
@forward "all-buttons";
|
|
6
|
+
@forward "all-text-inputs";
|
|
7
|
+
@forward "antialias";
|
|
8
|
+
@forward "aspect-ratio";
|
|
9
|
+
@forward "background-dots";
|
|
10
|
+
@forward "background-image";
|
|
11
|
+
@forward "background-stripes";
|
|
12
|
+
@forward "before";
|
|
13
|
+
@forward "border-box";
|
|
14
|
+
@forward "border-radius";
|
|
15
|
+
@forward "brand-logo";
|
|
16
|
+
@forward "breakpoint";
|
|
17
|
+
@forward "breakpointer";
|
|
18
|
+
@forward "center";
|
|
19
|
+
@forward "circle";
|
|
20
|
+
@forward "clearfix";
|
|
21
|
+
@forward "columnizer";
|
|
22
|
+
@forward "container";
|
|
23
|
+
@forward "container-query";
|
|
24
|
+
@forward "counter";
|
|
25
|
+
@forward "ellipsis";
|
|
26
|
+
@forward "escape-to-parent";
|
|
27
|
+
@forward "except";
|
|
28
|
+
@forward "focus-ring";
|
|
29
|
+
@forward "font-face";
|
|
30
|
+
@forward "hide";
|
|
31
|
+
@forward "line-clamp";
|
|
32
|
+
@forward "linear-gradient";
|
|
33
|
+
@forward "loadify";
|
|
34
|
+
@forward "motion-safe";
|
|
35
|
+
@forward "only";
|
|
36
|
+
@forward "placeholder";
|
|
37
|
+
@forward "placeholder-shown";
|
|
38
|
+
@forward "position";
|
|
39
|
+
@forward "radial-gradient";
|
|
40
|
+
@forward "remove";
|
|
41
|
+
@forward "reset-css";
|
|
42
|
+
@forward "reset-figure";
|
|
43
|
+
@forward "resizable";
|
|
44
|
+
@forward "responsive-image";
|
|
45
|
+
@forward "scissors";
|
|
46
|
+
@forward "screen-agent";
|
|
47
|
+
@forward "sizer";
|
|
48
|
+
@forward "smartphone";
|
|
49
|
+
@forward "sprite";
|
|
50
|
+
@forward "stretched-link";
|
|
51
|
+
@forward "tablet";
|
|
52
|
+
@forward "text-gradient";
|
|
53
|
+
@forward "text-image";
|
|
54
|
+
@forward "text-selection";
|
|
55
|
+
@forward "text-shadow";
|
|
56
|
+
@forward "text-stroke";
|
|
57
|
+
@forward "tokens";
|
|
58
|
+
@forward "triangle";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:math";
|
|
4
|
+
@use "sass:meta";
|
|
5
|
+
@use "../internal/is-css-function" as *;
|
|
6
|
+
|
|
7
|
+
// Truncates text after a number of lines. `ellipsis` does one line; this does
|
|
8
|
+
// several, and needs five declarations rather than one because -webkit-line-clamp
|
|
9
|
+
// only works alongside two other properties.
|
|
10
|
+
//
|
|
11
|
+
// All five were measured in a browser, on a paragraph that runs to five lines
|
|
12
|
+
// with a clamp of three:
|
|
13
|
+
//
|
|
14
|
+
// the three together 3 lines, with an ellipsis
|
|
15
|
+
// without -webkit-box-orient 5 lines, no clamping and no warning
|
|
16
|
+
// without display: -webkit-box 5 lines, likewise
|
|
17
|
+
// the standard line-clamp alone 5 lines; it is not Baseline yet
|
|
18
|
+
// without overflow: hidden the box is 3 lines, but the rest of the text
|
|
19
|
+
// spills out below it
|
|
20
|
+
//
|
|
21
|
+
// So the standard property is emitted for the future and the prefixed trio is
|
|
22
|
+
// what actually does the work today.
|
|
23
|
+
@mixin line-clamp($lines: 3) {
|
|
24
|
+
// var() is resolved by the browser, so only a literal count is checked.
|
|
25
|
+
@if $lines != none and not isCssFunction($lines, "var" "env") {
|
|
26
|
+
@if meta.type-of($lines) != "number" or not math.is-unitless($lines) {
|
|
27
|
+
@error "`#{$lines}` is not a valid $lines for `line-clamp`. Pass a whole number of lines, or `none` to undo a clamp.";
|
|
28
|
+
}
|
|
29
|
+
@if $lines < 1 or $lines != math.round($lines) {
|
|
30
|
+
@error "`#{$lines}` is not a valid $lines for `line-clamp`. Pass a whole number of lines that is at least 1, or `none` to undo a clamp.";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
display: -webkit-box;
|
|
34
|
+
-webkit-box-orient: vertical;
|
|
35
|
+
-webkit-line-clamp: $lines;
|
|
36
|
+
line-clamp: $lines;
|
|
37
|
+
overflow: hidden;
|
|
38
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "sass:map";
|
|
5
|
+
@use "sass:math";
|
|
6
|
+
@use "sass:meta";
|
|
7
|
+
@use "../maps/map-for-directions" as *;
|
|
8
|
+
@use "../internal/color-stops-problem" as *;
|
|
9
|
+
|
|
10
|
+
@mixin linear-gradient($direction, $colors) {
|
|
11
|
+
// A stop the browser does not keep drops the whole gradient; see
|
|
12
|
+
// scss/internal/_color-stops-problem.scss for what was measured.
|
|
13
|
+
$problem: colorStopsProblem($colors);
|
|
14
|
+
@if $problem {
|
|
15
|
+
@error "`#{meta.inspect($colors)}` is not a valid $colors for `linear-gradient`: #{$problem}. A browser drops the whole gradient.";
|
|
16
|
+
}
|
|
17
|
+
$list: ();
|
|
18
|
+
@for $i from 1 through list.length($colors) {
|
|
19
|
+
$list: list.append($list, list.nth($colors, $i), comma);
|
|
20
|
+
}
|
|
21
|
+
@if map.has-key($map-for-directions, $direction) {
|
|
22
|
+
background: linear-gradient(
|
|
23
|
+
map.get($map-for-directions, $direction),
|
|
24
|
+
$list
|
|
25
|
+
);
|
|
26
|
+
} @else if not map.has-key($map-for-directions, $direction) {
|
|
27
|
+
@if meta.type-of($direction) != "number" or not list.index("deg", math.unit($direction)) {
|
|
28
|
+
@error "`#{$direction}` is not a valid $direction for `linear-gradient`. Pass an angle such as `45deg`, or one of: #{map.keys($map-for-directions)}.";
|
|
29
|
+
} @else {
|
|
30
|
+
background: linear-gradient($direction, $list);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "sass:meta";
|
|
5
|
+
@use "../utilities/is-time" as *;
|
|
6
|
+
|
|
7
|
+
// `init` defines the %loadify placeholder, and every call extends it. Under the
|
|
8
|
+
// module system a selector can only extend a placeholder from a module it
|
|
9
|
+
// loads, so the file with the call must be the file that calls `init`, or must
|
|
10
|
+
// `@use` it. Anything else fails with "The target selector was not found".
|
|
11
|
+
// An entry file calling `init` does not help a partial it loads, since the
|
|
12
|
+
// partial does not load the entry file. Stylesheets using @import share one
|
|
13
|
+
// scope and are unaffected.
|
|
14
|
+
@mixin loadify($params...) {
|
|
15
|
+
@if not & {
|
|
16
|
+
@if list.length($params) == 0 or (list.length($params) == 1 and list.nth($params, 1) == "init") {
|
|
17
|
+
@keyframes loadify {
|
|
18
|
+
to {
|
|
19
|
+
opacity: 1;
|
|
20
|
+
visibility: visible;
|
|
21
|
+
backface-visibility: visible;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
%loadify {
|
|
25
|
+
opacity: 0;
|
|
26
|
+
visibility: hidden;
|
|
27
|
+
backface-visibility: hidden;
|
|
28
|
+
animation-name: loadify;
|
|
29
|
+
animation-fill-mode: forwards;
|
|
30
|
+
|
|
31
|
+
// The element starts invisible and the animation is what reveals it,
|
|
32
|
+
// so switching the animation off is not enough on its own: it would
|
|
33
|
+
// leave the content hidden for good. Under reduced motion the end
|
|
34
|
+
// state is applied directly instead, and nothing moves.
|
|
35
|
+
@media (prefers-reduced-motion: reduce) {
|
|
36
|
+
opacity: 1;
|
|
37
|
+
visibility: visible;
|
|
38
|
+
backface-visibility: visible;
|
|
39
|
+
animation: none;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
} @else if (list.length($params) == 1 and list.nth($params, 1) != "init") or (list.length($params) == 1 and meta.type-of(list.nth($params, 1)) != "string") {
|
|
43
|
+
@error "#{list.nth($params, 1)} is not a valid argument. Please pass `init` as an argument to initialize the effect or do not pass any argument at all.";
|
|
44
|
+
} @else if list.length($params) > 1 {
|
|
45
|
+
@error "Only one argument is allowed when you call this mixin at the root of your stylesheet! Please pass `init` as an argument to initialize the effect or do not pass any argument at all.";
|
|
46
|
+
}
|
|
47
|
+
} @else if & {
|
|
48
|
+
@extend %loadify;
|
|
49
|
+
@if list.length($params) == 0 {
|
|
50
|
+
animation-delay: 0.2s;
|
|
51
|
+
animation-duration: 0.5s;
|
|
52
|
+
} @else if list.length($params) == 1 {
|
|
53
|
+
animation-delay: #{isTime(list.nth($params, 1))};
|
|
54
|
+
animation-duration: 0.5s;
|
|
55
|
+
} @else if list.length($params) == 2 {
|
|
56
|
+
animation-delay: #{isTime(list.nth($params, 1))};
|
|
57
|
+
animation-duration: #{isTime(list.nth($params, 2))};
|
|
58
|
+
} @else if list.length($params) > 2 {
|
|
59
|
+
@error "You cannot pass more than two arguments.";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:meta";
|
|
4
|
+
|
|
5
|
+
// Applies its content only for users who have not asked their system for less
|
|
6
|
+
// motion. Motion is opt-in here rather than switched off afterwards: the usual
|
|
7
|
+
// way round writes the animation and then overrides it under
|
|
8
|
+
// `prefers-reduced-motion: reduce`, and that override has to catch every
|
|
9
|
+
// animation and transition, including the ones added later. Written inside this
|
|
10
|
+
// block, nothing moves for a user who asked for less, without a list to keep.
|
|
11
|
+
//
|
|
12
|
+
// Two agent trials wrote this same wrapper by hand, as `motion-safe` and
|
|
13
|
+
// `motion-ok`. Both media queries were checked to parse in Chrome 152; the
|
|
14
|
+
// reduced-motion setting itself could not be emulated in the browser used.
|
|
15
|
+
//
|
|
16
|
+
// The trap is the resting state. An element hidden in its base rule and
|
|
17
|
+
// revealed by an animation inside the block stays hidden when the block does
|
|
18
|
+
// not apply, which is what `loadify` avoids by applying the end state. Keep the
|
|
19
|
+
// visible state in the base rule and the start of the motion in the keyframes.
|
|
20
|
+
@mixin motion-safe {
|
|
21
|
+
@if not meta.content-exists() {
|
|
22
|
+
@error "`motion-safe` wraps the motion you pass it, so call it with a block, such as `.card { @include motion-safe { transition: transform 0.2s; } }`.";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
26
|
+
@content;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "sass:meta";
|
|
5
|
+
@use "sass:string";
|
|
6
|
+
@use "../internal/sibling-index" as *;
|
|
7
|
+
|
|
8
|
+
@mixin only($params...) {
|
|
9
|
+
@if list.length($params) == 0 {
|
|
10
|
+
@error "Please pass an argument. The argument must be either a negative or positive number or list of numbers. Or pass one of the following predefined string values: 'first', 'last', 'odd', 'even'.";
|
|
11
|
+
} @else if list.length($params) == 1 {
|
|
12
|
+
$value: list.nth($params, 1);
|
|
13
|
+
@if meta.type-of($value) == "number" {
|
|
14
|
+
// A unit or a fraction makes a selector the browser drops, and 0 matches
|
|
15
|
+
// nothing; see scss/internal/_sibling-index.scss.
|
|
16
|
+
$problem: siblingIndexProblem($value, "only");
|
|
17
|
+
@if $problem {
|
|
18
|
+
@error "`#{meta.inspect($value)}` is not a valid position for `only`: #{$problem}.";
|
|
19
|
+
}
|
|
20
|
+
@if $value < 0 {
|
|
21
|
+
&:nth-last-of-type(#{$value * -1}) {
|
|
22
|
+
@content;
|
|
23
|
+
}
|
|
24
|
+
} @else {
|
|
25
|
+
&:nth-of-type(#{$value}) {
|
|
26
|
+
@content;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
} @else if meta.type-of($value) == "string" {
|
|
30
|
+
@if $value == "odd" {
|
|
31
|
+
&:nth-of-type(odd) {
|
|
32
|
+
@content;
|
|
33
|
+
}
|
|
34
|
+
} @else if $value == "even" {
|
|
35
|
+
&:nth-of-type(even) {
|
|
36
|
+
@content;
|
|
37
|
+
}
|
|
38
|
+
} @else if $value == "first" {
|
|
39
|
+
&:first-of-type {
|
|
40
|
+
@content;
|
|
41
|
+
}
|
|
42
|
+
} @else if $value == "last" {
|
|
43
|
+
&:last-of-type {
|
|
44
|
+
@content;
|
|
45
|
+
}
|
|
46
|
+
} @else {
|
|
47
|
+
// For class, id or attribute selectors.
|
|
48
|
+
&#{$value} {
|
|
49
|
+
@content;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
} @else {
|
|
53
|
+
@error "`#{$value}` is not a valid argument for `only`. Pass a positive or negative number, one of `first`, `last`, `odd`, `even`, or a selector such as `.foo`.";
|
|
54
|
+
}
|
|
55
|
+
} @else if list.length($params) > 1 {
|
|
56
|
+
// Every item is checked first. A word used to fail with Sass's own
|
|
57
|
+
// `Undefined operation`, and one bad position emptied the whole selector
|
|
58
|
+
// list, taking the good positions with it.
|
|
59
|
+
@each $item in $params {
|
|
60
|
+
$problem: siblingIndexProblem($item, "only", true);
|
|
61
|
+
@if $problem {
|
|
62
|
+
@error "`#{meta.inspect($item)}` is not a valid position for `only`: #{$problem}.";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
$list: ();
|
|
66
|
+
@for $i from 1 through list.length($params) {
|
|
67
|
+
$list: list.append($list, if(list.nth($params, $i) < 0, string.unquote("&:nth-last-of-type(#{list.nth($params, $i) * -1})"), string.unquote("&:nth-of-type(#{list.nth($params, $i)})")), comma);
|
|
68
|
+
}
|
|
69
|
+
#{$list} {
|
|
70
|
+
@content;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@mixin placeholder {
|
|
4
|
+
&::-webkit-input-placeholder {
|
|
5
|
+
@content;
|
|
6
|
+
}
|
|
7
|
+
&::-moz-placeholder {
|
|
8
|
+
@content;
|
|
9
|
+
}
|
|
10
|
+
&:-ms-input-placeholder {
|
|
11
|
+
@content;
|
|
12
|
+
}
|
|
13
|
+
&:-moz-placeholder {
|
|
14
|
+
@content;
|
|
15
|
+
}
|
|
16
|
+
&::placeholder {
|
|
17
|
+
@content;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "sass:meta";
|
|
5
|
+
@use "sass:string";
|
|
6
|
+
@use "../utilities/shorthand-property" as *;
|
|
7
|
+
@use "../internal/keyword-value" as *;
|
|
8
|
+
@use "../internal/length-problem" as *;
|
|
9
|
+
|
|
10
|
+
// Sets position and its four offsets in shorthand order: top, right, bottom,
|
|
11
|
+
// left, as `margin` and `padding` take them.
|
|
12
|
+
//
|
|
13
|
+
// Pass $logical: true for the offsets that follow the writing direction, the
|
|
14
|
+
// same choice `triangle` and `border-radius` offer with their logical names.
|
|
15
|
+
// The shorthand order stays the same and each position maps to its logical
|
|
16
|
+
// twin: top to inset-block-start, right to inset-inline-end, bottom to
|
|
17
|
+
// inset-block-end, left to inset-inline-start. Measured in Chrome 152: under
|
|
18
|
+
// dir="ltr" each logical offset put the box where its physical twin did, and
|
|
19
|
+
// under dir="rtl" where the mirrored twin did, while a physical `left: 16px`
|
|
20
|
+
// stayed 16px from the left in both. For one offset, writing inset-* by hand is
|
|
21
|
+
// as short; the argument is here so the library behaves the same way
|
|
22
|
+
// everywhere.
|
|
23
|
+
@mixin position($position: absolute, $offsets: 0, $logical: false) {
|
|
24
|
+
// null is read as false, as a null argument means "not set" across the
|
|
25
|
+
// library, so a caller can pass a variable that may be unset.
|
|
26
|
+
@if $logical != true and $logical != false and $logical != null {
|
|
27
|
+
@error "`#{meta.inspect($logical)}` is not a valid $logical for `position`. Pass true for offsets that follow the writing direction, or false for top, right, bottom and left.";
|
|
28
|
+
}
|
|
29
|
+
// Measured in Chrome 152, `position` kept the five keywords in any case, the
|
|
30
|
+
// CSS-wide keywords and var(), and dropped anything else, a quoted keyword
|
|
31
|
+
// included. A vendor keyword is let through: Chrome drops `-webkit-sticky`,
|
|
32
|
+
// which Safari uses. null leaves position out, as it always has.
|
|
33
|
+
$problem: keywordProblem($position, "static" "relative" "absolute" "fixed" "sticky", $vendor: true);
|
|
34
|
+
@if $problem {
|
|
35
|
+
@error "`#{meta.inspect($position)}` is not a valid $position for `position`: #{$problem}. A browser drops the declaration.";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
$offsets: shorthandProperty($offsets);
|
|
39
|
+
// Each offset is a declaration of its own. Measured in Chrome 152, top, left
|
|
40
|
+
// and the inset-* properties kept a length, a negative length, a percentage,
|
|
41
|
+
// 0, auto and a CSS-wide keyword in any case, var(), maths functions, anchor()
|
|
42
|
+
// and anchor-size(), and dropped any other word, a unitless number, a unit
|
|
43
|
+
// that is not a length, a colour, an image and a quoted length. This used to
|
|
44
|
+
// go through validateLength, which only warns, and warned about working
|
|
45
|
+
// values such as AUTO and revert-layer while saying nothing about 10deg or
|
|
46
|
+
// url(); validateLength itself is unchanged, for callers who want a warning.
|
|
47
|
+
@each $value in $offsets {
|
|
48
|
+
@if $value != null {
|
|
49
|
+
$problem: lengthProblem($value, $keywords: ("auto",), $functions: "anchor" "anchor-size", $css-wide: true);
|
|
50
|
+
@if $problem {
|
|
51
|
+
@error "`#{meta.inspect($value)}` is not a valid offset for `position`: #{$problem}. A browser drops the declaration.";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
$edges: top right bottom left;
|
|
56
|
+
@if $logical {
|
|
57
|
+
$edges: inset-block-start inset-inline-end inset-block-end inset-inline-start;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Written without quotes, since `position: "sticky"` was dropped.
|
|
61
|
+
@if meta.type-of($position) == "string" {
|
|
62
|
+
position: string.unquote($position);
|
|
63
|
+
} @else {
|
|
64
|
+
position: $position;
|
|
65
|
+
}
|
|
66
|
+
@for $i from 1 through 4 {
|
|
67
|
+
$value: list.nth($offsets, $i);
|
|
68
|
+
@if $value != null {
|
|
69
|
+
#{list.nth($edges, $i)}: $value;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|