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,184 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "sass:map";
|
|
5
|
+
@use "sass:meta";
|
|
6
|
+
@use "sass:string";
|
|
7
|
+
@use "../maps/map-for-positions" as *;
|
|
8
|
+
@use "../internal/is-condition-value" as *;
|
|
9
|
+
@use "../internal/words" as *;
|
|
10
|
+
@use "../internal/color-stops-problem" as *;
|
|
11
|
+
|
|
12
|
+
// The mixin writes `radial-gradient($shape $position, ...)`, so $shape carries
|
|
13
|
+
// the shape and may carry a size, and a $position that is not a key from
|
|
14
|
+
// $map-for-positions carries a size, `at` and a position, or both. Each is
|
|
15
|
+
// checked against what Chrome 152 kept in `background-image`, in any case:
|
|
16
|
+
//
|
|
17
|
+
// - kept: circle, ellipse, an extent keyword such as closest-side, a length
|
|
18
|
+
// (`circle 10px`, `10px`), two lengths or percentages (`ellipse 10% 20%`),
|
|
19
|
+
// `at` followed by one or two keywords from left, center, right, top and
|
|
20
|
+
// bottom or up to four keywords and lengths (`at left 10px top 20px`), and
|
|
21
|
+
// var() or calc() anywhere;
|
|
22
|
+
// - dropped: a word outside those (`huge`, `auto`, `inherit`), a percentage or a
|
|
23
|
+
// negative length as a circle's size (`circle 10%`, `circle -10px`), the
|
|
24
|
+
// shape twice (`circle circle`), four keywords after `at`, and the logical
|
|
25
|
+
// keywords `at x-start` and `at block-start`.
|
|
26
|
+
//
|
|
27
|
+
// It checks each part on its own, so a shape in one argument and a size in the
|
|
28
|
+
// other that do not fit together, such as `ellipse` with a single length, are
|
|
29
|
+
// not caught.
|
|
30
|
+
$-extents: "closest-side" "closest-corner" "farthest-side" "farthest-corner";
|
|
31
|
+
$-places: "left" "center" "right" "top" "bottom";
|
|
32
|
+
|
|
33
|
+
// "extent", "length" or "percentage" for a word that can size the gradient,
|
|
34
|
+
// or null.
|
|
35
|
+
@function -size-kind($word) {
|
|
36
|
+
$lower: string.to-lower-case("#{$word}");
|
|
37
|
+
@if list.index($-extents, $lower) {
|
|
38
|
+
@return "extent";
|
|
39
|
+
}
|
|
40
|
+
@if string.index($lower, "-") == 1 {
|
|
41
|
+
@return null;
|
|
42
|
+
}
|
|
43
|
+
@if isConditionValue($word, "length") {
|
|
44
|
+
@return "length";
|
|
45
|
+
}
|
|
46
|
+
@if isConditionValue($word, "length-percentage") {
|
|
47
|
+
@return "percentage";
|
|
48
|
+
}
|
|
49
|
+
@return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Checks the size words before `at`. $shape is the shape named, or null.
|
|
53
|
+
@function -size-problem($words, $shape) {
|
|
54
|
+
$extents: 0;
|
|
55
|
+
$lengths: 0;
|
|
56
|
+
$percentages: 0;
|
|
57
|
+
@each $word in $words {
|
|
58
|
+
$kind: -size-kind($word);
|
|
59
|
+
@if $kind == null {
|
|
60
|
+
@return "`#{$word}` is not a shape, an extent keyword such as `closest-side`, or a length";
|
|
61
|
+
} @else if $kind == "extent" {
|
|
62
|
+
$extents: $extents + 1;
|
|
63
|
+
} @else if $kind == "length" {
|
|
64
|
+
$lengths: $lengths + 1;
|
|
65
|
+
} @else {
|
|
66
|
+
$percentages: $percentages + 1;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
$sizes: $lengths + $percentages;
|
|
70
|
+
@if $extents > 1 or ($extents == 1 and $sizes > 0) {
|
|
71
|
+
@return "it gives the size twice";
|
|
72
|
+
}
|
|
73
|
+
@if $sizes > 2 {
|
|
74
|
+
@return "a size is one length or two";
|
|
75
|
+
}
|
|
76
|
+
@if $sizes == 1 and ($percentages == 1 or $shape == "ellipse") {
|
|
77
|
+
@return "one size is a circle's radius, which is a length and not a percentage";
|
|
78
|
+
}
|
|
79
|
+
@if $sizes == 2 and $shape == "circle" {
|
|
80
|
+
@return "a circle takes one length, not two";
|
|
81
|
+
}
|
|
82
|
+
@return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@function -shape-problem($shape) {
|
|
86
|
+
@if string.index($shape, "(") {
|
|
87
|
+
@return null;
|
|
88
|
+
}
|
|
89
|
+
$named: null;
|
|
90
|
+
$sizes: ();
|
|
91
|
+
@each $word in wordsOf($shape) {
|
|
92
|
+
$lower: string.to-lower-case($word);
|
|
93
|
+
@if list.index("circle" "ellipse", $lower) {
|
|
94
|
+
@if $named {
|
|
95
|
+
@return "it names the shape twice";
|
|
96
|
+
}
|
|
97
|
+
$named: $lower;
|
|
98
|
+
} @else {
|
|
99
|
+
$sizes: list.append($sizes, $word);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
@return -size-problem($sizes, $named);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@function -position-problem($position) {
|
|
106
|
+
@if map.has-key($map-for-positions, $position) or string.index($position, "(") {
|
|
107
|
+
@return null;
|
|
108
|
+
}
|
|
109
|
+
$sizes: ();
|
|
110
|
+
$places: ();
|
|
111
|
+
$after-at: false;
|
|
112
|
+
@each $word in wordsOf($position) {
|
|
113
|
+
$lower: string.to-lower-case($word);
|
|
114
|
+
@if $lower == "at" {
|
|
115
|
+
@if $after-at {
|
|
116
|
+
@return "it has `at` twice";
|
|
117
|
+
}
|
|
118
|
+
$after-at: true;
|
|
119
|
+
} @else if $after-at {
|
|
120
|
+
$places: list.append($places, $word);
|
|
121
|
+
} @else if list.index("circle" "ellipse", $lower) {
|
|
122
|
+
@return "the shape goes in $shape, not $position";
|
|
123
|
+
} @else {
|
|
124
|
+
$sizes: list.append($sizes, $word);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
$problem: -size-problem($sizes, null);
|
|
128
|
+
@if $problem {
|
|
129
|
+
@return "#{$problem}. Pass a position name such as `center` or `top-left`, an extent keyword such as `closest-side`, or `at` followed by a position, such as `at 30% 40%`";
|
|
130
|
+
}
|
|
131
|
+
@if $after-at and list.length($places) == 0 {
|
|
132
|
+
@return "`at` needs a position after it, such as `at center`";
|
|
133
|
+
}
|
|
134
|
+
@if list.length($places) > 4 {
|
|
135
|
+
@return "a position takes at most four values";
|
|
136
|
+
}
|
|
137
|
+
$keywords: 0;
|
|
138
|
+
@each $word in $places {
|
|
139
|
+
@if list.index($-places, string.to-lower-case($word)) {
|
|
140
|
+
$keywords: $keywords + 1;
|
|
141
|
+
} @else if not isConditionValue($word, "length-percentage") {
|
|
142
|
+
@return "`#{$word}` is not a position; after `at` pass left, center, right, top, bottom or a length";
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
@if $keywords > 2 and $keywords == list.length($places) {
|
|
146
|
+
@return "a position of keywords alone takes at most two, such as `at top left`";
|
|
147
|
+
}
|
|
148
|
+
@return null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@mixin radial-gradient($shape, $position, $colors) {
|
|
152
|
+
@if meta.type-of($shape) != "string" {
|
|
153
|
+
@error "`#{$shape}` is not a valid $shape for `radial-gradient`. Pass `circle` or `ellipse`.";
|
|
154
|
+
}
|
|
155
|
+
@if meta.type-of($position) != "string" {
|
|
156
|
+
@error "`#{$position}` is not a valid $position for `radial-gradient`. Pass a position name such as `center` or `top-left`, or a raw CSS position as a string.";
|
|
157
|
+
}
|
|
158
|
+
$list: ();
|
|
159
|
+
$shape: string.unquote($shape);
|
|
160
|
+
$position: string.unquote($position);
|
|
161
|
+
$problem: -shape-problem($shape);
|
|
162
|
+
@if $problem {
|
|
163
|
+
@error "`#{$shape}` is not a valid $shape for `radial-gradient`: #{$problem}. A browser drops the whole gradient.";
|
|
164
|
+
}
|
|
165
|
+
$problem: -position-problem($position);
|
|
166
|
+
@if $problem {
|
|
167
|
+
@error "`#{$position}` is not a valid $position for `radial-gradient`: #{$problem}. A browser drops the whole gradient.";
|
|
168
|
+
}
|
|
169
|
+
$problem: colorStopsProblem($colors);
|
|
170
|
+
@if $problem {
|
|
171
|
+
@error "`#{meta.inspect($colors)}` is not a valid $colors for `radial-gradient`: #{$problem}. A browser drops the whole gradient.";
|
|
172
|
+
}
|
|
173
|
+
@for $i from 1 through list.length($colors) {
|
|
174
|
+
$list: list.append($list, list.nth($colors, $i), comma);
|
|
175
|
+
}
|
|
176
|
+
@if map.has-key($map-for-positions, $position) {
|
|
177
|
+
background: radial-gradient(
|
|
178
|
+
$shape map.get($map-for-positions, $position),
|
|
179
|
+
$list
|
|
180
|
+
);
|
|
181
|
+
} @else if not map.has-key($map-for-positions, $position) {
|
|
182
|
+
background: radial-gradient($shape $position, $list);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "../library/breakpoint" as *;
|
|
5
|
+
|
|
6
|
+
@mixin remove($params...) {
|
|
7
|
+
@if list.length($params) == 0 {
|
|
8
|
+
display: none;
|
|
9
|
+
} @else if list.length($params) == 1 {
|
|
10
|
+
$value: list.nth($params, 1);
|
|
11
|
+
// `only` rather than the one-argument form, which compiles to the same
|
|
12
|
+
// query, so the warning below names `remove` and is printed once.
|
|
13
|
+
@include breakpoint(only, $value) {
|
|
14
|
+
display: none;
|
|
15
|
+
}
|
|
16
|
+
@warn "`remove(#{$value})` hides the element only at a viewport exactly that wide, a single pixel. Write `remove(only, #{$value})` for that width, or `remove(min, #{$value})` from it upwards.";
|
|
17
|
+
} @else if list.length($params) == 2 {
|
|
18
|
+
@if list.index("min" "max", list.nth($params, 1)) {
|
|
19
|
+
$mode: list.nth($params, 1);
|
|
20
|
+
$value: list.nth($params, 2);
|
|
21
|
+
@if $mode == "min" {
|
|
22
|
+
@include breakpoint(min, $value) {
|
|
23
|
+
display: none;
|
|
24
|
+
}
|
|
25
|
+
} @else if $mode == "max" {
|
|
26
|
+
@include breakpoint(max, $value) {
|
|
27
|
+
display: none;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
} @else {
|
|
31
|
+
$start: list.nth($params, 1);
|
|
32
|
+
$end: list.nth($params, 2);
|
|
33
|
+
@include breakpoint($start, $end) {
|
|
34
|
+
display: none;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
} @else {
|
|
38
|
+
@error "`remove` takes at most 2 arguments; you passed #{list.length($params)}. Pass nothing to hide the element outright, one breakpoint, `min`/`max` plus a breakpoint, or a start and an end breakpoint.";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@mixin reset-css {
|
|
4
|
+
@if & {
|
|
5
|
+
@error "Please call the mixin at the root of your style sheet.";
|
|
6
|
+
} @else {
|
|
7
|
+
// http://meyerweb.com/eric/tools/css/reset/
|
|
8
|
+
// v2.0 | 20110126
|
|
9
|
+
// License: none (public domain)
|
|
10
|
+
//
|
|
11
|
+
// Comments in this file are `//`: a /* */ comment inside a mixin is emitted
|
|
12
|
+
// into the stylesheet of everyone who includes it.
|
|
13
|
+
html, body, div, span, applet, object, iframe,
|
|
14
|
+
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
|
15
|
+
a, abbr, acronym, address, big, cite, code,
|
|
16
|
+
del, dfn, em, img, ins, kbd, q, s, samp,
|
|
17
|
+
small, strike, strong, sub, sup, tt, var,
|
|
18
|
+
b, u, i, center,
|
|
19
|
+
dl, dt, dd, ol, ul, li,
|
|
20
|
+
fieldset, form, label, legend,
|
|
21
|
+
table, caption, tbody, tfoot, thead, tr, th, td,
|
|
22
|
+
article, aside, canvas, details, embed,
|
|
23
|
+
figure, figcaption, footer, header, hgroup,
|
|
24
|
+
menu, nav, output, ruby, section, summary,
|
|
25
|
+
time, mark, audio, video {
|
|
26
|
+
margin: 0;
|
|
27
|
+
padding: 0;
|
|
28
|
+
border: 0;
|
|
29
|
+
font-size: 100%;
|
|
30
|
+
font: inherit;
|
|
31
|
+
vertical-align: baseline;
|
|
32
|
+
}
|
|
33
|
+
// HTML5 display-role reset for older browsers
|
|
34
|
+
article, aside, details, figcaption, figure,
|
|
35
|
+
footer, header, hgroup, menu, main, nav, section {
|
|
36
|
+
display: block;
|
|
37
|
+
}
|
|
38
|
+
body {
|
|
39
|
+
line-height: 1;
|
|
40
|
+
}
|
|
41
|
+
ol, ul {
|
|
42
|
+
list-style: none;
|
|
43
|
+
}
|
|
44
|
+
blockquote, q {
|
|
45
|
+
quotes: none;
|
|
46
|
+
}
|
|
47
|
+
blockquote:before, blockquote:after,
|
|
48
|
+
q:before, q:after {
|
|
49
|
+
content: '';
|
|
50
|
+
content: none;
|
|
51
|
+
}
|
|
52
|
+
table {
|
|
53
|
+
border-collapse: collapse;
|
|
54
|
+
border-spacing: 0;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:meta";
|
|
4
|
+
@use "sass:string";
|
|
5
|
+
@use "../internal/keyword-value" as *;
|
|
6
|
+
|
|
7
|
+
// Measured in Chrome 152, `resize` kept none, both, horizontal, vertical, block,
|
|
8
|
+
// inline and auto, and `overflow` one or two of visible, hidden, clip, scroll,
|
|
9
|
+
// auto and overlay, all in any case, with the CSS-wide keywords on their own and
|
|
10
|
+
// var(). Both dropped a quoted keyword, three overflow values, and a CSS-wide
|
|
11
|
+
// keyword beside another, such as `overflow: inherit auto`. null leaves the
|
|
12
|
+
// declaration out, as it always has.
|
|
13
|
+
@mixin resizable($direction: both, $overflow: auto) {
|
|
14
|
+
$problem: keywordProblem($direction, "none" "both" "horizontal" "vertical" "block" "inline" "auto");
|
|
15
|
+
@if $problem {
|
|
16
|
+
@error "`#{meta.inspect($direction)}` is not a valid $direction for `resizable`: #{$problem}. A browser drops the declaration.";
|
|
17
|
+
}
|
|
18
|
+
$problem: keywordProblem($overflow, "visible" "hidden" "clip" "scroll" "auto" "overlay", 2);
|
|
19
|
+
@if $problem {
|
|
20
|
+
@error "`#{meta.inspect($overflow)}` is not a valid $overflow for `resizable`: #{$problem}. A browser drops the declaration.";
|
|
21
|
+
}
|
|
22
|
+
// Written without quotes, since `resize: "both"` was dropped.
|
|
23
|
+
@if meta.type-of($direction) == "string" {
|
|
24
|
+
resize: string.unquote($direction);
|
|
25
|
+
} @else {
|
|
26
|
+
resize: $direction;
|
|
27
|
+
}
|
|
28
|
+
@if meta.type-of($overflow) == "string" {
|
|
29
|
+
overflow: string.unquote($overflow);
|
|
30
|
+
} @else {
|
|
31
|
+
overflow: $overflow;
|
|
32
|
+
}
|
|
33
|
+
max-width: 100%;
|
|
34
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "../utilities/validate-scissors" as *;
|
|
5
|
+
|
|
6
|
+
@mixin scissors($corners) {
|
|
7
|
+
@if list.length($corners) == 1 {
|
|
8
|
+
$corners: validateScissors($corners);
|
|
9
|
+
clip-path: polygon(
|
|
10
|
+
0 #{list.nth($corners, 1)},
|
|
11
|
+
#{list.nth($corners, 1)} 0,
|
|
12
|
+
calc(100% - #{list.nth($corners, 1)}) 0,
|
|
13
|
+
100% #{list.nth($corners, 1)},
|
|
14
|
+
100% calc(100% - #{list.nth($corners, 1)}),
|
|
15
|
+
calc(100% - #{list.nth($corners, 1)}) 100%,
|
|
16
|
+
#{list.nth($corners, 1)} 100%,
|
|
17
|
+
0 calc(100% - #{list.nth($corners, 1)})
|
|
18
|
+
);
|
|
19
|
+
} @else if list.length($corners) == 4 {
|
|
20
|
+
$corners: validateScissors($corners);
|
|
21
|
+
clip-path: polygon(
|
|
22
|
+
0 #{list.nth($corners, 1)},
|
|
23
|
+
#{list.nth($corners, 1)} 0,
|
|
24
|
+
calc(100% - #{list.nth($corners, 2)}) 0,
|
|
25
|
+
100% #{list.nth($corners, 2)},
|
|
26
|
+
100% calc(100% - #{list.nth($corners, 3)}),
|
|
27
|
+
calc(100% - #{list.nth($corners, 3)}) 100%,
|
|
28
|
+
#{list.nth($corners, 4)} 100%,
|
|
29
|
+
0 calc(100% - #{list.nth($corners, 4)})
|
|
30
|
+
);
|
|
31
|
+
} @else {
|
|
32
|
+
@error "`scissors` takes either 1 corner size or 4; you passed #{list.length($corners)}. Pass one length to cut every corner equally, or four lengths in top-left, top-right, bottom-right, bottom-left order.";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:meta";
|
|
4
|
+
@use "../internal/custom-property-in" as *;
|
|
5
|
+
@use "../internal/is-condition-value" as *;
|
|
6
|
+
|
|
7
|
+
@mixin screen-agent($resolution) {
|
|
8
|
+
$custom-property: customPropertyIn($resolution);
|
|
9
|
+
@if $custom-property {
|
|
10
|
+
@error "`#{$custom-property}` cannot be used as a resolution: custom properties are not evaluated in a @media condition, so the rule would never apply. Pass `1x`, `2x`, `3x` or a resolution such as `2dppx`.";
|
|
11
|
+
}
|
|
12
|
+
@if $resolution == "1x" {
|
|
13
|
+
@media (min-resolution: 96dpi) {
|
|
14
|
+
@content;
|
|
15
|
+
}
|
|
16
|
+
} @else if $resolution == "2x" {
|
|
17
|
+
@media (min-resolution: 192dpi) {
|
|
18
|
+
@content;
|
|
19
|
+
}
|
|
20
|
+
} @else if $resolution == "3x" {
|
|
21
|
+
@media (min-resolution: 288dpi) {
|
|
22
|
+
@content;
|
|
23
|
+
}
|
|
24
|
+
} @else {
|
|
25
|
+
// Measured in Chrome 152, `(min-resolution: huge)`, `(min-resolution: 2)`,
|
|
26
|
+
// `(min-resolution: 10px)` and `(min-resolution: -1dppx)` never match.
|
|
27
|
+
@if not isConditionValue($resolution, "resolution") {
|
|
28
|
+
@error "`#{meta.inspect($resolution)}` is not a valid $resolution for `screen-agent`: `(min-resolution: #{meta.inspect($resolution)})` would never match. Pass `1x`, `2x`, `3x`, or a resolution such as `2dppx`, `192dpi` or `38dpcm`.";
|
|
29
|
+
}
|
|
30
|
+
@media (min-resolution: #{$resolution}) {
|
|
31
|
+
@content;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:meta";
|
|
4
|
+
@use "../internal/length-problem" as *;
|
|
5
|
+
|
|
6
|
+
@mixin sizer($width, $height: $width) {
|
|
7
|
+
@each $name, $value in ("$width": $width, "$height": $height) {
|
|
8
|
+
$problem: sizeProblem($value);
|
|
9
|
+
@if $problem {
|
|
10
|
+
@error "`#{meta.inspect($value)}` is not a valid #{$name} for `sizer`: #{$problem}. A browser drops the declaration.";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
width: $width;
|
|
14
|
+
height: $height;
|
|
15
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:map";
|
|
4
|
+
@use "../maps/map-for-smartphones" as *;
|
|
5
|
+
@use "../utilities/map-deep-get" as *;
|
|
6
|
+
|
|
7
|
+
@mixin smartphone($device, $orientation: null) {
|
|
8
|
+
@if map.has-key($map-for-smartphones, $device) {
|
|
9
|
+
@if $orientation == portrait or $orientation == null {
|
|
10
|
+
@media only screen
|
|
11
|
+
and (device-width: mapDeepGet($map-for-smartphones, $device, 'width'))
|
|
12
|
+
and (device-height: mapDeepGet($map-for-smartphones, $device, 'height'))
|
|
13
|
+
and (orientation: portrait) {
|
|
14
|
+
@content;
|
|
15
|
+
}
|
|
16
|
+
} @else if $orientation == landscape {
|
|
17
|
+
@media only screen
|
|
18
|
+
and (device-width: mapDeepGet($map-for-smartphones, $device, 'height'))
|
|
19
|
+
and (device-height: mapDeepGet($map-for-smartphones, $device, 'width'))
|
|
20
|
+
and (orientation: landscape) {
|
|
21
|
+
@content;
|
|
22
|
+
}
|
|
23
|
+
} @else {
|
|
24
|
+
@error "`#{$orientation}` is not a valid $orientation for `smartphone`. Pass `portrait`, `landscape`, or no orientation at all.";
|
|
25
|
+
}
|
|
26
|
+
} @else {
|
|
27
|
+
@error "`#{$device}` is not a device known to `smartphone`. Pass one of: #{map.keys($map-for-smartphones)}.";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "sass:meta";
|
|
5
|
+
@use "sass:string";
|
|
6
|
+
@use "../internal/length-problem" as *;
|
|
7
|
+
|
|
8
|
+
$-places: "left" "center" "right" "top" "bottom";
|
|
9
|
+
|
|
10
|
+
// What is wrong with $position as a background-position, or null. Measured in
|
|
11
|
+
// Chrome 152, background-position kept one or two lengths, percentages or
|
|
12
|
+
// place keywords, keywords with offsets such as `left 10px top 5px`, var(),
|
|
13
|
+
// maths functions and a CSS-wide keyword alone. It dropped a unitless number
|
|
14
|
+
// other than 0, a unit that is not a length, any other word or colour, an image,
|
|
15
|
+
// and three or four lengths with no keyword. Interpolation, as in
|
|
16
|
+
// `#{$x}px #{$y}px`, gives the same value as strings, so each part is read.
|
|
17
|
+
@function -position-problem($position) {
|
|
18
|
+
$parts: $position;
|
|
19
|
+
@if meta.type-of($position) == "string" and string.slice(meta.inspect($position), 1, 1) != "\"" and not string.index($position, "(") and string.index($position, " ") {
|
|
20
|
+
$parts: ();
|
|
21
|
+
$text: $position;
|
|
22
|
+
$at: string.index($text, " ");
|
|
23
|
+
@while $at {
|
|
24
|
+
@if $at > 1 {
|
|
25
|
+
$parts: list.append($parts, string.unquote(string.slice($text, 1, $at - 1)));
|
|
26
|
+
}
|
|
27
|
+
$text: string.slice($text, $at + 1);
|
|
28
|
+
$at: string.index($text, " ");
|
|
29
|
+
}
|
|
30
|
+
$parts: list.append($parts, string.unquote($text));
|
|
31
|
+
} @else if meta.type-of($position) != "list" {
|
|
32
|
+
$parts: ($position,);
|
|
33
|
+
}
|
|
34
|
+
@if list.length($parts) > 4 {
|
|
35
|
+
@return "a background position takes at most four values";
|
|
36
|
+
}
|
|
37
|
+
$keywords: 0;
|
|
38
|
+
@each $part in $parts {
|
|
39
|
+
@if meta.type-of($part) == "string" and list.index($-places, string.to-lower-case($part)) {
|
|
40
|
+
$keywords: $keywords + 1;
|
|
41
|
+
} @else {
|
|
42
|
+
$problem: lengthProblem($part, $css-wide: list.length($parts) == 1);
|
|
43
|
+
@if $problem == "it is not a length" {
|
|
44
|
+
@return "`#{meta.inspect($part)}` is not a length or one of left, center, right, top or bottom";
|
|
45
|
+
} @else if $problem {
|
|
46
|
+
@return "in `#{meta.inspect($part)}`, #{$problem}";
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
@if list.length($parts) > 2 and $keywords == 0 {
|
|
51
|
+
@return "three or four values need place keywords, such as `left 10px top 5px`";
|
|
52
|
+
}
|
|
53
|
+
@return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@mixin sprite($params...) {
|
|
57
|
+
@if list.length($params) == 1 {
|
|
58
|
+
@if meta.type-of(list.nth($params, 1)) == "string" {
|
|
59
|
+
$str-length: string.length(list.nth($params, 1));
|
|
60
|
+
$str-end: string.slice(list.nth($params, 1), $str-length - 3);
|
|
61
|
+
@if list.index(".png" ".jpg" ".svg", $str-end) {
|
|
62
|
+
$image-url: list.nth($params, 1);
|
|
63
|
+
display: inline-block;
|
|
64
|
+
background-image: url($image-url);
|
|
65
|
+
background-repeat: no-repeat;
|
|
66
|
+
} @else {
|
|
67
|
+
@error "`#{list.nth($params, 1)}` is not a valid image path for `sprite`. The path must end in .png, .jpg or .svg.";
|
|
68
|
+
}
|
|
69
|
+
} @else {
|
|
70
|
+
$position: list.nth($params, 1);
|
|
71
|
+
$problem: -position-problem($position);
|
|
72
|
+
@if $problem {
|
|
73
|
+
@error "`#{meta.inspect($position)}` is not a valid position for `sprite`: #{$problem}. A browser drops the declaration.";
|
|
74
|
+
}
|
|
75
|
+
background-position: $position;
|
|
76
|
+
}
|
|
77
|
+
} @else if list.length($params) == 2 {
|
|
78
|
+
$image-url: list.nth($params, 1);
|
|
79
|
+
$position: list.nth($params, 2);
|
|
80
|
+
// The one-argument form checks its path; this one did not, so a list was
|
|
81
|
+
// written into url(), which a browser drops, and a number asked for a file
|
|
82
|
+
// of that name. Measured in Chrome 152: `url(16 9)` was dropped.
|
|
83
|
+
@if meta.type-of($image-url) != "string" {
|
|
84
|
+
@error "`#{meta.inspect($image-url)}` is not a valid image path for `sprite`: with two arguments the first is one path as a string, and a browser drops a list in `url()`. Pass a path such as `\"/img/sprite.png\"`, then the position.";
|
|
85
|
+
}
|
|
86
|
+
@if $position != null {
|
|
87
|
+
$problem: -position-problem($position);
|
|
88
|
+
@if $problem {
|
|
89
|
+
@error "`#{meta.inspect($position)}` is not a valid position for `sprite`: #{$problem}. A browser drops the declaration.";
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
display: inline-block;
|
|
93
|
+
background-image: url($image-url);
|
|
94
|
+
background-position: $position;
|
|
95
|
+
background-repeat: no-repeat;
|
|
96
|
+
} @else {
|
|
97
|
+
@error "`sprite` takes 1 or 2 arguments; you passed #{list.length($params)}. Pass an image path, a background position, or both in that order.";
|
|
98
|
+
}
|
|
99
|
+
@content;
|
|
100
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
|
|
5
|
+
@mixin stretched-link($value: "before") {
|
|
6
|
+
@if list.index("before" "after", $value) {
|
|
7
|
+
&#{"::" + $value} {
|
|
8
|
+
content: "";
|
|
9
|
+
position: absolute;
|
|
10
|
+
pointer-events: auto;
|
|
11
|
+
background-color: rgba(0, 0, 0, 0);
|
|
12
|
+
top: 0;
|
|
13
|
+
right: 0;
|
|
14
|
+
bottom: 0;
|
|
15
|
+
left: 0;
|
|
16
|
+
z-index: 1;
|
|
17
|
+
}
|
|
18
|
+
} @else {
|
|
19
|
+
@error "'#{$value}' is a wrong argument. This mixin accepts 'before' or 'after' as an argument. If you don't pass any argument default it will target the '::before' pseudo-element of the selected element.";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:map";
|
|
4
|
+
@use "../maps/map-for-tablets" as *;
|
|
5
|
+
@use "../utilities/map-deep-get" as *;
|
|
6
|
+
|
|
7
|
+
@mixin tablet($device, $orientation: null) {
|
|
8
|
+
@if map.has-key($map-for-tablets, $device) {
|
|
9
|
+
@if $orientation == portrait or $orientation == null {
|
|
10
|
+
@media only screen
|
|
11
|
+
and (device-width: mapDeepGet($map-for-tablets, $device, 'width'))
|
|
12
|
+
and (device-height: mapDeepGet($map-for-tablets, $device, 'height'))
|
|
13
|
+
and (orientation: portrait) {
|
|
14
|
+
@content;
|
|
15
|
+
}
|
|
16
|
+
} @else if $orientation == landscape {
|
|
17
|
+
@media only screen
|
|
18
|
+
and (device-width: mapDeepGet($map-for-tablets, $device, 'height'))
|
|
19
|
+
and (device-height: mapDeepGet($map-for-tablets, $device, 'width'))
|
|
20
|
+
and (orientation: landscape) {
|
|
21
|
+
@content;
|
|
22
|
+
}
|
|
23
|
+
} @else {
|
|
24
|
+
@error "`#{$orientation}` is not a valid $orientation for `tablet`. Pass `portrait`, `landscape`, or no orientation at all.";
|
|
25
|
+
}
|
|
26
|
+
} @else {
|
|
27
|
+
@error "`#{$device}` is not a device known to `tablet`. Pass one of: #{map.keys($map-for-tablets)}.";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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 text-gradient($direction, $colors) {
|
|
11
|
+
// A stop the browser does not keep drops the whole gradient, and with it the
|
|
12
|
+
// text, which this mixin makes transparent; see
|
|
13
|
+
// scss/internal/_color-stops-problem.scss.
|
|
14
|
+
$problem: colorStopsProblem($colors);
|
|
15
|
+
@if $problem {
|
|
16
|
+
@error "`#{meta.inspect($colors)}` is not a valid $colors for `text-gradient`: #{$problem}. A browser drops the whole gradient, and the transparent text with it.";
|
|
17
|
+
}
|
|
18
|
+
$list: ();
|
|
19
|
+
@for $i from 1 through list.length($colors) {
|
|
20
|
+
$list: list.append($list, list.nth($colors, $i), comma);
|
|
21
|
+
}
|
|
22
|
+
@if map.has-key($map-for-directions, $direction) {
|
|
23
|
+
background: linear-gradient(
|
|
24
|
+
map.get($map-for-directions, $direction),
|
|
25
|
+
$list
|
|
26
|
+
);
|
|
27
|
+
} @else if not map.has-key($map-for-directions, $direction) {
|
|
28
|
+
@if meta.type-of($direction) != "number" or not list.index("deg", math.unit($direction)) {
|
|
29
|
+
@error "`#{$direction}` is not a valid $direction for `text-gradient`. Pass an angle such as `45deg`, or one of: #{map.keys($map-for-directions)}.";
|
|
30
|
+
} @else {
|
|
31
|
+
background: linear-gradient($direction, $list);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
-webkit-background-clip: text;
|
|
35
|
+
-webkit-text-fill-color: transparent;
|
|
36
|
+
background-clip: text;
|
|
37
|
+
color: transparent;
|
|
38
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "../internal/image-value" as *;
|
|
4
|
+
|
|
5
|
+
@mixin text-image($image: null) {
|
|
6
|
+
@if $image {
|
|
7
|
+
background-image: imageValue($image, "text-image", "$image");
|
|
8
|
+
}
|
|
9
|
+
background-size: cover;
|
|
10
|
+
background-position: center;
|
|
11
|
+
-webkit-background-clip: text;
|
|
12
|
+
-webkit-text-fill-color: transparent;
|
|
13
|
+
background-clip: text;
|
|
14
|
+
color: transparent;
|
|
15
|
+
}
|