Open Source Compliance • Functional Safety • Education
25 |
34 |
35 |
36 |
37 |
40 |
41 |
42 |
43 |
48 |
49 |
--------------------------------------------------------------------------------
/assets/sass/libs/_functions.scss:
--------------------------------------------------------------------------------
1 | /// Removes a specific item from a list.
2 | /// @author Hugo Giraudel
3 | /// @param {list} $list List.
4 | /// @param {integer} $index Index.
5 | /// @return {list} Updated list.
6 | @function remove-nth($list, $index) {
7 |
8 | $result: null;
9 |
10 | @if type-of($index) != number {
11 | @warn "$index: #{quote($index)} is not a number for `remove-nth`.";
12 | }
13 | @else if $index == 0 {
14 | @warn "List index 0 must be a non-zero integer for `remove-nth`.";
15 | }
16 | @else if abs($index) > length($list) {
17 | @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`.";
18 | }
19 | @else {
20 |
21 | $result: ();
22 | $index: if($index < 0, length($list) + $index + 1, $index);
23 |
24 | @for $i from 1 through length($list) {
25 |
26 | @if $i != $index {
27 | $result: append($result, nth($list, $i));
28 | }
29 |
30 | }
31 |
32 | }
33 |
34 | @return $result;
35 |
36 | }
37 |
38 | /// Gets a value from a map.
39 | /// @author Hugo Giraudel
40 | /// @param {map} $map Map.
41 | /// @param {string} $keys Key(s).
42 | /// @return {string} Value.
43 | @function val($map, $keys...) {
44 |
45 | @if nth($keys, 1) == null {
46 | $keys: remove-nth($keys, 1);
47 | }
48 |
49 | @each $key in $keys {
50 | $map: map-get($map, $key);
51 | }
52 |
53 | @return $map;
54 |
55 | }
56 |
57 | /// Gets a duration value.
58 | /// @param {string} $keys Key(s).
59 | /// @return {string} Value.
60 | @function _duration($keys...) {
61 | @return val($duration, $keys...);
62 | }
63 |
64 | /// Gets a font value.
65 | /// @param {string} $keys Key(s).
66 | /// @return {string} Value.
67 | @function _font($keys...) {
68 | @return val($font, $keys...);
69 | }
70 |
71 | /// Gets a misc value.
72 | /// @param {string} $keys Key(s).
73 | /// @return {string} Value.
74 | @function _misc($keys...) {
75 | @return val($misc, $keys...);
76 | }
77 |
78 | /// Gets a palette value.
79 | /// @param {string} $keys Key(s).
80 | /// @return {string} Value.
81 | @function _palette($keys...) {
82 | @return val($palette, $keys...);
83 | }
84 |
85 | /// Gets a size value.
86 | /// @param {string} $keys Key(s).
87 | /// @return {string} Value.
88 | @function _size($keys...) {
89 | @return val($size, $keys...);
90 | }
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | Aerial by HTML5 UP
2 | html5up.net | @ajlkn
3 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
4 |
5 |
6 | This is Aerial, a single page, single screen responsive site template. Real simple.
7 | Makes heavy use of CSS animation (something I've been messing with a lot lately).
8 | Should work well as a landing page that just directs folks to your stuff elsewhere
9 | on the www. Sass sources are also included, so if you've never used Sass and you're
10 | interested in giving it a try, head on over to sass-lang.com (and if not, you can
11 | safely delete the "sass/" folder).
12 |
13 | The scrolling mountainous background was derived from "Icefields" by Ryan Schroeder,
14 | a talented photographer from Vancouver who graciously released it on Unsplash under
15 | the CC0 license. Be sure to check out his other stuff over at flickr (link below)
16 | as well as all the other kickass CC0-licensed images at Unsplash (unsplash.com).
17 |
18 | Questions/comments/issues = just email or find me on Twitter. Have fun!
19 |
20 | AJ
21 | aj@lkn.io | @ajlkn
22 |
23 |
24 | The Scrolling Background:
25 |
26 | This relies entirely on CSS to do its thing, which is cool, but that makes
27 | changing it a bit weird/tricky at first. You can still use pretty much any image
28 | you want, but for best results make sure yours is:
29 |
30 | - Horizontally tileable.
31 | - Wide and short.
32 | - About 1500px wide.
33 | - Fades to a solid color either at the top of bottom (which is used to fill
34 | the empty space above or below your image).
35 |
36 | Now, there are two ways to use it: with CSS, or with Sass:
37 |
38 | CSS:
39 |
40 | Look for this line in css/style.css (line 108 as of this writing):
41 |
42 | background: #348cb2 url("images/bg.jpg") bottom left;
43 |
44 | and use it to set the page background color, URL, and placement of
45 | your image. It should be as close to 1500px wide as you can get it.
46 |
47 | Sass:
48 |
49 | Set the value of $bg to the page background color, URL, and placement
50 | of your image. Change $bg-width if your image is something other than
51 | 1500px wide.
52 |
53 |
54 | Credits:
55 |
56 | Background Image:
57 | Ryan Schroeder via Unsplash (unsplash.com - CC0 licensed)
58 | "Icefields" (flickr.com/photos/ryanschroeder/11876741703)
59 |
60 | Icons:
61 | Font Awesome (fontawesome.io)
62 |
63 | Other:
64 | Responsive Tools (github.com/ajlkn/responsive-tools)
--------------------------------------------------------------------------------
/assets/sass/libs/_mixins.scss:
--------------------------------------------------------------------------------
1 | /// Makes an element's :before pseudoelement a FontAwesome icon.
2 | /// @param {string} $content Optional content value to use.
3 | /// @param {string} $category Optional category to use.
4 | /// @param {string} $where Optional pseudoelement to target (before or after).
5 | @mixin icon($content: false, $category: regular, $where: before) {
6 |
7 | text-decoration: none;
8 |
9 | &:#{$where} {
10 |
11 | @if $content {
12 | content: $content;
13 | }
14 |
15 | -moz-osx-font-smoothing: grayscale;
16 | -webkit-font-smoothing: antialiased;
17 | display: inline-block;
18 | font-style: normal;
19 | font-variant: normal;
20 | text-rendering: auto;
21 | line-height: 1;
22 | text-transform: none !important;
23 |
24 | @if ($category == brands) {
25 | font-family: 'Font Awesome 5 Brands';
26 | }
27 | @elseif ($category == solid) {
28 | font-family: 'Font Awesome 5 Free';
29 | font-weight: 900;
30 | }
31 | @else {
32 | font-family: 'Font Awesome 5 Free';
33 | font-weight: 400;
34 | }
35 |
36 | }
37 |
38 | }
39 |
40 | /// Applies padding to an element, taking the current element-margin value into account.
41 | /// @param {mixed} $tb Top/bottom padding.
42 | /// @param {mixed} $lr Left/right padding.
43 | /// @param {list} $pad Optional extra padding (in the following order top, right, bottom, left)
44 | /// @param {bool} $important If true, adds !important.
45 | @mixin padding($tb, $lr, $pad: (0,0,0,0), $important: null) {
46 |
47 | @if $important {
48 | $important: '!important';
49 | }
50 |
51 | $x: 0.1em;
52 |
53 | @if unit(_size(element-margin)) == 'rem' {
54 | $x: 0.1rem;
55 | }
56 |
57 | padding: ($tb + nth($pad,1)) ($lr + nth($pad,2)) max($x, $tb - _size(element-margin) + nth($pad,3)) ($lr + nth($pad,4)) #{$important};
58 |
59 | }
60 |
61 | /// Encodes a SVG data URL so IE doesn't choke (via codepen.io/jakob-e/pen/YXXBrp).
62 | /// @param {string} $svg SVG data URL.
63 | /// @return {string} Encoded SVG data URL.
64 | @function svg-url($svg) {
65 |
66 | $svg: str-replace($svg, '"', '\'');
67 | $svg: str-replace($svg, '%', '%25');
68 | $svg: str-replace($svg, '<', '%3C');
69 | $svg: str-replace($svg, '>', '%3E');
70 | $svg: str-replace($svg, '&', '%26');
71 | $svg: str-replace($svg, '#', '%23');
72 | $svg: str-replace($svg, '{', '%7B');
73 | $svg: str-replace($svg, '}', '%7D');
74 | $svg: str-replace($svg, ';', '%3B');
75 |
76 | @return url("data:image/svg+xml;charset=utf8,#{$svg}");
77 |
78 | }
--------------------------------------------------------------------------------
/assets/sass/libs/_breakpoints.scss:
--------------------------------------------------------------------------------
1 | // breakpoints.scss v1.0 | @ajlkn | MIT licensed */
2 |
3 | // Vars.
4 |
5 | /// Breakpoints.
6 | /// @var {list}
7 | $breakpoints: () !global;
8 |
9 | // Mixins.
10 |
11 | /// Sets breakpoints.
12 | /// @param {map} $x Breakpoints.
13 | @mixin breakpoints($x: ()) {
14 | $breakpoints: $x !global;
15 | }
16 |
17 | /// Wraps @content in a @media block targeting a specific orientation.
18 | /// @param {string} $orientation Orientation.
19 | @mixin orientation($orientation) {
20 | @media screen and (orientation: #{$orientation}) {
21 | @content;
22 | }
23 | }
24 |
25 | /// Wraps @content in a @media block using a given query.
26 | /// @param {string} $query Query.
27 | @mixin breakpoint($query: null) {
28 |
29 | $breakpoint: null;
30 | $op: null;
31 | $media: null;
32 |
33 | // Determine operator, breakpoint.
34 |
35 | // Greater than or equal.
36 | @if (str-slice($query, 0, 2) == '>=') {
37 |
38 | $op: 'gte';
39 | $breakpoint: str-slice($query, 3);
40 |
41 | }
42 |
43 | // Less than or equal.
44 | @elseif (str-slice($query, 0, 2) == '<=') {
45 |
46 | $op: 'lte';
47 | $breakpoint: str-slice($query, 3);
48 |
49 | }
50 |
51 | // Greater than.
52 | @elseif (str-slice($query, 0, 1) == '>') {
53 |
54 | $op: 'gt';
55 | $breakpoint: str-slice($query, 2);
56 |
57 | }
58 |
59 | // Less than.
60 | @elseif (str-slice($query, 0, 1) == '<') {
61 |
62 | $op: 'lt';
63 | $breakpoint: str-slice($query, 2);
64 |
65 | }
66 |
67 | // Not.
68 | @elseif (str-slice($query, 0, 1) == '!') {
69 |
70 | $op: 'not';
71 | $breakpoint: str-slice($query, 2);
72 |
73 | }
74 |
75 | // Equal.
76 | @else {
77 |
78 | $op: 'eq';
79 | $breakpoint: $query;
80 |
81 | }
82 |
83 | // Build media.
84 | @if ($breakpoint and map-has-key($breakpoints, $breakpoint)) {
85 |
86 | $a: map-get($breakpoints, $breakpoint);
87 |
88 | // Range.
89 | @if (type-of($a) == 'list') {
90 |
91 | $x: nth($a, 1);
92 | $y: nth($a, 2);
93 |
94 | // Max only.
95 | @if ($x == null) {
96 |
97 | // Greater than or equal (>= 0 / anything)
98 | @if ($op == 'gte') {
99 | $media: 'screen';
100 | }
101 |
102 | // Less than or equal (<= y)
103 | @elseif ($op == 'lte') {
104 | $media: 'screen and (max-width: ' + $y + ')';
105 | }
106 |
107 | // Greater than (> y)
108 | @elseif ($op == 'gt') {
109 | $media: 'screen and (min-width: ' + ($y + 1) + ')';
110 | }
111 |
112 | // Less than (< 0 / invalid)
113 | @elseif ($op == 'lt') {
114 | $media: 'screen and (max-width: -1px)';
115 | }
116 |
117 | // Not (> y)
118 | @elseif ($op == 'not') {
119 | $media: 'screen and (min-width: ' + ($y + 1) + ')';
120 | }
121 |
122 | // Equal (<= y)
123 | @else {
124 | $media: 'screen and (max-width: ' + $y + ')';
125 | }
126 |
127 | }
128 |
129 | // Min only.
130 | @else if ($y == null) {
131 |
132 | // Greater than or equal (>= x)
133 | @if ($op == 'gte') {
134 | $media: 'screen and (min-width: ' + $x + ')';
135 | }
136 |
137 | // Less than or equal (<= inf / anything)
138 | @elseif ($op == 'lte') {
139 | $media: 'screen';
140 | }
141 |
142 | // Greater than (> inf / invalid)
143 | @elseif ($op == 'gt') {
144 | $media: 'screen and (max-width: -1px)';
145 | }
146 |
147 | // Less than (< x)
148 | @elseif ($op == 'lt') {
149 | $media: 'screen and (max-width: ' + ($x - 1) + ')';
150 | }
151 |
152 | // Not (< x)
153 | @elseif ($op == 'not') {
154 | $media: 'screen and (max-width: ' + ($x - 1) + ')';
155 | }
156 |
157 | // Equal (>= x)
158 | @else {
159 | $media: 'screen and (min-width: ' + $x + ')';
160 | }
161 |
162 | }
163 |
164 | // Min and max.
165 | @else {
166 |
167 | // Greater than or equal (>= x)
168 | @if ($op == 'gte') {
169 | $media: 'screen and (min-width: ' + $x + ')';
170 | }
171 |
172 | // Less than or equal (<= y)
173 | @elseif ($op == 'lte') {
174 | $media: 'screen and (max-width: ' + $y + ')';
175 | }
176 |
177 | // Greater than (> y)
178 | @elseif ($op == 'gt') {
179 | $media: 'screen and (min-width: ' + ($y + 1) + ')';
180 | }
181 |
182 | // Less than (< x)
183 | @elseif ($op == 'lt') {
184 | $media: 'screen and (max-width: ' + ($x - 1) + ')';
185 | }
186 |
187 | // Not (< x and > y)
188 | @elseif ($op == 'not') {
189 | $media: 'screen and (max-width: ' + ($x - 1) + '), screen and (min-width: ' + ($y + 1) + ')';
190 | }
191 |
192 | // Equal (>= x and <= y)
193 | @else {
194 | $media: 'screen and (min-width: ' + $x + ') and (max-width: ' + $y + ')';
195 | }
196 |
197 | }
198 |
199 | }
200 |
201 | // String.
202 | @else {
203 |
204 | // Missing a media type? Prefix with "screen".
205 | @if (str-slice($a, 0, 1) == '(') {
206 | $media: 'screen and ' + $a;
207 | }
208 |
209 | // Otherwise, use as-is.
210 | @else {
211 | $media: $a;
212 | }
213 |
214 | }
215 |
216 | }
217 |
218 | // Output.
219 | @media #{$media} {
220 | @content;
221 | }
222 |
223 | }
--------------------------------------------------------------------------------
/assets/sass/libs/_vendor.scss:
--------------------------------------------------------------------------------
1 | // vendor.scss v1.0 | @ajlkn | MIT licensed */
2 |
3 | // Vars.
4 |
5 | /// Vendor prefixes.
6 | /// @var {list}
7 | $vendor-prefixes: (
8 | '-moz-',
9 | '-webkit-',
10 | '-ms-',
11 | ''
12 | );
13 |
14 | /// Properties that should be vendorized.
15 | /// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org
16 | /// @var {list}
17 | $vendor-properties: (
18 |
19 | // Animation.
20 | 'animation',
21 | 'animation-delay',
22 | 'animation-direction',
23 | 'animation-duration',
24 | 'animation-fill-mode',
25 | 'animation-iteration-count',
26 | 'animation-name',
27 | 'animation-play-state',
28 | 'animation-timing-function',
29 |
30 | // Appearance.
31 | 'appearance',
32 |
33 | // Backdrop filter.
34 | 'backdrop-filter',
35 |
36 | // Background image options.
37 | 'background-clip',
38 | 'background-origin',
39 | 'background-size',
40 |
41 | // Box sizing.
42 | 'box-sizing',
43 |
44 | // Clip path.
45 | 'clip-path',
46 |
47 | // Filter effects.
48 | 'filter',
49 |
50 | // Flexbox.
51 | 'align-content',
52 | 'align-items',
53 | 'align-self',
54 | 'flex',
55 | 'flex-basis',
56 | 'flex-direction',
57 | 'flex-flow',
58 | 'flex-grow',
59 | 'flex-shrink',
60 | 'flex-wrap',
61 | 'justify-content',
62 | 'order',
63 |
64 | // Font feature.
65 | 'font-feature-settings',
66 | 'font-language-override',
67 | 'font-variant-ligatures',
68 |
69 | // Font kerning.
70 | 'font-kerning',
71 |
72 | // Fragmented borders and backgrounds.
73 | 'box-decoration-break',
74 |
75 | // Grid layout.
76 | 'grid-column',
77 | 'grid-column-align',
78 | 'grid-column-end',
79 | 'grid-column-start',
80 | 'grid-row',
81 | 'grid-row-align',
82 | 'grid-row-end',
83 | 'grid-row-start',
84 | 'grid-template-columns',
85 | 'grid-template-rows',
86 |
87 | // Hyphens.
88 | 'hyphens',
89 | 'word-break',
90 |
91 | // Masks.
92 | 'mask',
93 | 'mask-border',
94 | 'mask-border-outset',
95 | 'mask-border-repeat',
96 | 'mask-border-slice',
97 | 'mask-border-source',
98 | 'mask-border-width',
99 | 'mask-clip',
100 | 'mask-composite',
101 | 'mask-image',
102 | 'mask-origin',
103 | 'mask-position',
104 | 'mask-repeat',
105 | 'mask-size',
106 |
107 | // Multicolumn.
108 | 'break-after',
109 | 'break-before',
110 | 'break-inside',
111 | 'column-count',
112 | 'column-fill',
113 | 'column-gap',
114 | 'column-rule',
115 | 'column-rule-color',
116 | 'column-rule-style',
117 | 'column-rule-width',
118 | 'column-span',
119 | 'column-width',
120 | 'columns',
121 |
122 | // Object fit.
123 | 'object-fit',
124 | 'object-position',
125 |
126 | // Regions.
127 | 'flow-from',
128 | 'flow-into',
129 | 'region-fragment',
130 |
131 | // Scroll snap points.
132 | 'scroll-snap-coordinate',
133 | 'scroll-snap-destination',
134 | 'scroll-snap-points-x',
135 | 'scroll-snap-points-y',
136 | 'scroll-snap-type',
137 |
138 | // Shapes.
139 | 'shape-image-threshold',
140 | 'shape-margin',
141 | 'shape-outside',
142 |
143 | // Tab size.
144 | 'tab-size',
145 |
146 | // Text align last.
147 | 'text-align-last',
148 |
149 | // Text decoration.
150 | 'text-decoration-color',
151 | 'text-decoration-line',
152 | 'text-decoration-skip',
153 | 'text-decoration-style',
154 |
155 | // Text emphasis.
156 | 'text-emphasis',
157 | 'text-emphasis-color',
158 | 'text-emphasis-position',
159 | 'text-emphasis-style',
160 |
161 | // Text size adjust.
162 | 'text-size-adjust',
163 |
164 | // Text spacing.
165 | 'text-spacing',
166 |
167 | // Transform.
168 | 'transform',
169 | 'transform-origin',
170 |
171 | // Transform 3D.
172 | 'backface-visibility',
173 | 'perspective',
174 | 'perspective-origin',
175 | 'transform-style',
176 |
177 | // Transition.
178 | 'transition',
179 | 'transition-delay',
180 | 'transition-duration',
181 | 'transition-property',
182 | 'transition-timing-function',
183 |
184 | // Unicode bidi.
185 | 'unicode-bidi',
186 |
187 | // User select.
188 | 'user-select',
189 |
190 | // Writing mode.
191 | 'writing-mode',
192 |
193 | );
194 |
195 | /// Values that should be vendorized.
196 | /// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org
197 | /// @var {list}
198 | $vendor-values: (
199 |
200 | // Cross fade.
201 | 'cross-fade',
202 |
203 | // Element function.
204 | 'element',
205 |
206 | // Filter function.
207 | 'filter',
208 |
209 | // Flexbox.
210 | 'flex',
211 | 'inline-flex',
212 |
213 | // Grab cursors.
214 | 'grab',
215 | 'grabbing',
216 |
217 | // Gradients.
218 | 'linear-gradient',
219 | 'repeating-linear-gradient',
220 | 'radial-gradient',
221 | 'repeating-radial-gradient',
222 |
223 | // Grid layout.
224 | 'grid',
225 | 'inline-grid',
226 |
227 | // Image set.
228 | 'image-set',
229 |
230 | // Intrinsic width.
231 | 'max-content',
232 | 'min-content',
233 | 'fit-content',
234 | 'fill',
235 | 'fill-available',
236 | 'stretch',
237 |
238 | // Sticky position.
239 | 'sticky',
240 |
241 | // Transform.
242 | 'transform',
243 |
244 | // Zoom cursors.
245 | 'zoom-in',
246 | 'zoom-out',
247 |
248 | );
249 |
250 | // Functions.
251 |
252 | /// Removes a specific item from a list.
253 | /// @author Hugo Giraudel
254 | /// @param {list} $list List.
255 | /// @param {integer} $index Index.
256 | /// @return {list} Updated list.
257 | @function remove-nth($list, $index) {
258 |
259 | $result: null;
260 |
261 | @if type-of($index) != number {
262 | @warn "$index: #{quote($index)} is not a number for `remove-nth`.";
263 | }
264 | @else if $index == 0 {
265 | @warn "List index 0 must be a non-zero integer for `remove-nth`.";
266 | }
267 | @else if abs($index) > length($list) {
268 | @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`.";
269 | }
270 | @else {
271 |
272 | $result: ();
273 | $index: if($index < 0, length($list) + $index + 1, $index);
274 |
275 | @for $i from 1 through length($list) {
276 |
277 | @if $i != $index {
278 | $result: append($result, nth($list, $i));
279 | }
280 |
281 | }
282 |
283 | }
284 |
285 | @return $result;
286 |
287 | }
288 |
289 | /// Replaces a substring within another string.
290 | /// @author Hugo Giraudel
291 | /// @param {string} $string String.
292 | /// @param {string} $search Substring.
293 | /// @param {string} $replace Replacement.
294 | /// @return {string} Updated string.
295 | @function str-replace($string, $search, $replace: '') {
296 |
297 | $index: str-index($string, $search);
298 |
299 | @if $index {
300 | @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
301 | }
302 |
303 | @return $string;
304 |
305 | }
306 |
307 | /// Replaces a substring within each string in a list.
308 | /// @param {list} $strings List of strings.
309 | /// @param {string} $search Substring.
310 | /// @param {string} $replace Replacement.
311 | /// @return {list} Updated list of strings.
312 | @function str-replace-all($strings, $search, $replace: '') {
313 |
314 | @each $string in $strings {
315 | $strings: set-nth($strings, index($strings, $string), str-replace($string, $search, $replace));
316 | }
317 |
318 | @return $strings;
319 |
320 | }
321 |
322 | // Mixins.
323 |
324 | /// Wraps @content in vendorized keyframe blocks.
325 | /// @param {string} $name Name.
326 | @mixin keyframes($name) {
327 |
328 | @-moz-keyframes #{$name} { @content; }
329 | @-webkit-keyframes #{$name} { @content; }
330 | @-ms-keyframes #{$name} { @content; }
331 | @keyframes #{$name} { @content; }
332 |
333 | }
334 |
335 | /// Vendorizes a declaration's property and/or value(s).
336 | /// @param {string} $property Property.
337 | /// @param {mixed} $value String/list of value(s).
338 | @mixin vendor($property, $value) {
339 |
340 | // Determine if property should expand.
341 | $expandProperty: index($vendor-properties, $property);
342 |
343 | // Determine if value should expand (and if so, add '-prefix-' placeholder).
344 | $expandValue: false;
345 |
346 | @each $x in $value {
347 | @each $y in $vendor-values {
348 | @if $y == str-slice($x, 1, str-length($y)) {
349 |
350 | $value: set-nth($value, index($value, $x), '-prefix-' + $x);
351 | $expandValue: true;
352 |
353 | }
354 | }
355 | }
356 |
357 | // Expand property?
358 | @if $expandProperty {
359 | @each $vendor in $vendor-prefixes {
360 | #{$vendor}#{$property}: #{str-replace-all($value, '-prefix-', $vendor)};
361 | }
362 | }
363 |
364 | // Expand just the value?
365 | @elseif $expandValue {
366 | @each $vendor in $vendor-prefixes {
367 | #{$property}: #{str-replace-all($value, '-prefix-', $vendor)};
368 | }
369 | }
370 |
371 | // Neither? Treat them as a normal declaration.
372 | @else {
373 | #{$property}: #{$value};
374 | }
375 |
376 | }
--------------------------------------------------------------------------------
/assets/sass/main.scss:
--------------------------------------------------------------------------------
1 | @import 'libs/vars';
2 | @import 'libs/functions';
3 | @import 'libs/mixins';
4 | @import 'libs/vendor';
5 | @import 'libs/breakpoints';
6 | @import url("https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,900");
7 | @import url("fontawesome-all.min.css");
8 |
9 | /*
10 | Aerial by HTML5 UP
11 | html5up.net | @ajlkn
12 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
13 | */
14 |
15 | // Breakpoints.
16 |
17 | @include breakpoints((
18 | wide: ( 1281px, 1680px ),
19 | normal: ( 737px, 1280px ),
20 | mobile: ( 481px, 736px ),
21 | mobilep: ( null, 480px )
22 | ));
23 |
24 | // Mixins.
25 |
26 | @mixin bg($width) {
27 | @include keyframes('bg') {
28 | 0% { @include vendor('transform', 'translate3d(0,0,0)'); }
29 | 100% { @include vendor('transform', 'translate3d(#{$width * -1},0,0)'); }
30 | }
31 |
32 | #bg {
33 | background-size: $width auto;
34 | width: ($width * 3);
35 | }
36 | }
37 |
38 | $delay-wrapper: _duration(wrapper) - 1s;
39 | $delay-overlay: $delay-wrapper - 0.5s;
40 | $delay-header: $delay-overlay + _duration(overlay) - 0.75s;
41 | $delay-nav-icons: $delay-header + _duration(header) - 1s;
42 | $delay-nav-icon: 0.25s;
43 |
44 | // Reset.
45 | // Based on meyerweb.com/eric/tools/css/reset (v2.0 | 20110126 | License: public domain)
46 |
47 | html, body, div, span, applet, object,
48 | iframe, h1, h2, h3, h4, h5, h6, p, blockquote,
49 | pre, a, abbr, acronym, address, big, cite,
50 | code, del, dfn, em, img, ins, kbd, q, s, samp,
51 | small, strike, strong, sub, sup, tt, var, b,
52 | u, i, center, dl, dt, dd, ol, ul, li, fieldset,
53 | form, label, legend, table, caption, tbody,
54 | tfoot, thead, tr, th, td, article, aside,
55 | canvas, details, embed, figure, figcaption,
56 | footer, header, hgroup, menu, nav, output, ruby,
57 | section, summary, time, mark, audio, video {
58 | margin: 0;
59 | padding: 0;
60 | border: 0;
61 | font-size: 100%;
62 | font: inherit;
63 | vertical-align: baseline;
64 | }
65 |
66 | article, aside, details, figcaption, figure,
67 | footer, header, hgroup, menu, nav, section {
68 | display: block;
69 | }
70 |
71 | body {
72 | line-height: 1;
73 | }
74 |
75 | ol, ul {
76 | list-style:none;
77 | }
78 |
79 | blockquote, q {
80 | quotes: none;
81 |
82 | &:before,
83 | &:after {
84 | content: '';
85 | content: none;
86 | }
87 | }
88 |
89 | table {
90 | border-collapse: collapse;
91 | border-spacing: 0;
92 | }
93 |
94 | body {
95 | -webkit-text-size-adjust: none;
96 | }
97 |
98 | mark {
99 | background-color: transparent;
100 | color: inherit;
101 | }
102 |
103 | input::-moz-focus-inner {
104 | border: 0;
105 | padding: 0;
106 | }
107 |
108 | input, select, textarea {
109 | -moz-appearance: none;
110 | -webkit-appearance: none;
111 | -ms-appearance: none;
112 | appearance: none;
113 | }
114 |
115 | /* Basic */
116 |
117 | // Set box model to border-box.
118 | // Based on css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice
119 | html {
120 | box-sizing: border-box;
121 | }
122 |
123 | *, *:before, *:after {
124 | box-sizing: inherit;
125 | }
126 |
127 | body {
128 | background: _palette(bg);
129 | overflow: hidden;
130 |
131 | // Stops initial animations until page loads.
132 | &.is-preload {
133 | *, *:before, *:after {
134 | @include vendor('animation', 'none !important');
135 | @include vendor('transition', 'none !important');
136 | }
137 | }
138 |
139 | }
140 |
141 | body, input, select, textarea {
142 | color: _palette(fg);
143 | font-family: 'Source Sans Pro', sans-serif;
144 | font-size: 15pt;
145 | font-weight: 300 !important;
146 | letter-spacing: -0.025em;
147 | line-height: 1.75em;
148 | }
149 |
150 | a {
151 | @include vendor('transition', 'border-color 0.2s ease-in-out');
152 | border-bottom: dotted 1px;
153 | color: inherit;
154 | outline: 0;
155 | text-decoration: none;
156 |
157 | &:hover {
158 | border-color: transparent;
159 | }
160 | }
161 |
162 | /* Icon */
163 |
164 | .icon {
165 | @include icon;
166 | position: relative;
167 |
168 | > .label {
169 | display: none;
170 | }
171 |
172 | &.solid {
173 | &:before {
174 | font-weight: 900;
175 | }
176 | }
177 |
178 | &.brands {
179 | &:before {
180 | font-family: 'Font Awesome 5 Brands';
181 | }
182 | }
183 | }
184 |
185 | /* Wrapper */
186 |
187 | @include keyframes('wrapper') {
188 | 0% { opacity: 0; }
189 | 100% { opacity: 1; }
190 | }
191 |
192 | #wrapper {
193 | @include vendor('animation', 'wrapper #{_duration(wrapper)} forwards');
194 | height: 100%;
195 | left: 0;
196 | opacity: 0;
197 | position: fixed;
198 | top: 0;
199 | width: 100%;
200 | }
201 |
202 | /* BG */
203 |
204 | #bg {
205 | @include vendor('animation', 'bg #{_duration(bg)} linear infinite');
206 | @include vendor('backface-visibility', 'hidden');
207 | @include vendor('transform', 'translate3d(0,0,0)');
208 |
209 | /* Set your background with this */
210 | background: _misc(bg);
211 |
212 | background-repeat: repeat-x;
213 | height: 100%;
214 | left: 0;
215 | opacity: 1;
216 | position: fixed;
217 | top: 0;
218 | }
219 |
220 | @include bg(_misc(bg-width) * 1.5);
221 |
222 | /* Overlay */
223 |
224 | @include keyframes('overlay') {
225 | 0% { opacity: 0; }
226 | 100% { opacity: 1; }
227 | }
228 |
229 | #overlay {
230 | @include vendor('animation', 'overlay #{_duration(overlay)} #{$delay-overlay} forwards');
231 | background-attachment: fixed, fixed;
232 | background-image: url('images/overlay-pattern.png'), url('images/overlay.svg');
233 | background-position: top left, center center;
234 | background-repeat: repeat, no-repeat;
235 | background-size: auto, cover;
236 | height: 100%;
237 | left: 0;
238 | opacity: 0;
239 | position: fixed;
240 | top: 0;
241 | width: 100%;
242 | }
243 |
244 | /* Main */
245 |
246 | #main {
247 | height: 100%;
248 | left: 0;
249 | position: fixed;
250 | text-align: center;
251 | top: 0;
252 | width: 100%;
253 |
254 | &:before {
255 | content: '';
256 | display: inline-block;
257 | height: 100%;
258 | margin-right: 0;
259 | vertical-align: middle;
260 | width: 1px;
261 | }
262 | }
263 |
264 | /* Header */
265 |
266 | @include keyframes('header') {
267 | 0% { @include vendor('transform', 'translate3d(0,1em,0)'); opacity: 0; }
268 | 100% { @include vendor('transform', 'translate3d(0,0,0)'); opacity: 1; }
269 | }
270 |
271 | @include keyframes('nav-icons') {
272 | 0% { @include vendor('transform', 'translate3d(0,1em,0)'); opacity: 0; }
273 | 100% { @include vendor('transform', 'translate3d(0,0,0)'); opacity: 1; }
274 | }
275 |
276 | #header {
277 | @include vendor('animation', 'header #{_duration(header)} #{$delay-header} forwards');
278 | @include vendor('backface-visibility', 'hidden');
279 | @include vendor('transform', 'translate3d(0,0,0)');
280 | cursor: default;
281 | display: inline-block;
282 | opacity: 0;
283 | position: relative;
284 | text-align: center;
285 | top: -1em;
286 | vertical-align: middle;
287 | width: 90%;
288 |
289 | h1 {
290 | font-size: 4.35em;
291 | font-weight: 900;
292 | letter-spacing: -0.035em;
293 | line-height: 1em;
294 | }
295 |
296 | p {
297 | font-size: 1.25em;
298 | margin: 0.75em 0 0.25em 0;
299 | opacity: 0.75;
300 | }
301 |
302 | nav {
303 | margin: 1.5em 0 0 0;
304 |
305 | li {
306 | @include vendor('animation', 'nav-icons #{_duration(nav-icons)} ease-in-out forwards');
307 | @include vendor('backface-visibility', 'hidden');
308 | @include vendor('transform', 'translate3d(0,0,0)');
309 | display: inline-block;
310 | height: _size(nav-icon-wrapper);
311 | line-height: _size(nav-icon-wrapper) * 1.1;
312 | opacity: 0;
313 | position: relative;
314 | top: 0;
315 | width: _size(nav-icon-wrapper);
316 |
317 | @for $x from 1 through 10 {
318 | &:nth-child(#{$x}) {
319 | @include vendor('animation-delay', ($delay-nav-icons + ($x * $delay-nav-icon)) + '');
320 | }
321 | }
322 | }
323 |
324 | a {
325 | -webkit-tap-highlight-color: rgba(0,0,0,0);
326 | -webkit-touch-callout: none;
327 | border: 0;
328 | display: inline-block;
329 |
330 | &:before {
331 | @include vendor('transition', 'all 0.2s ease-in-out');
332 | border-radius: 100%;
333 | border: solid 1px _palette(fg);
334 | display: block;
335 | font-size: _size(nav-icon);
336 | height: 2.5em;
337 | line-height: 2.5em;
338 | position: relative;
339 | text-align: center;
340 | top: 0;
341 | width: 2.5em;
342 | }
343 |
344 | &:hover {
345 | font-size: 1.1em;
346 |
347 | &:before {
348 | background-color: _palette(nav-icon, hover-bg);
349 | color: _palette(nav-icon, hover-fg);
350 | }
351 | }
352 |
353 | &:active {
354 | font-size: 0.95em;
355 | background: none;
356 |
357 | &:before {
358 | background-color: _palette(nav-icon, active-bg);
359 | color: _palette(nav-icon, active-fg);
360 | }
361 | }
362 |
363 | span {
364 | display: none;
365 | }
366 | }
367 | }
368 | }
369 |
370 | /* Footer */
371 |
372 | #footer {
373 | @include vendor('background-image', 'linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,0.5) 75%)');
374 | bottom: 0;
375 | cursor: default;
376 | height: 6em;
377 | left: 0;
378 | line-height: 8em;
379 | position: absolute;
380 | text-align: center;
381 | width: 100%;
382 | }
383 |
384 | /* Wide */
385 |
386 | @include breakpoint('<=wide') {
387 |
388 | /* Basic */
389 |
390 | body, input, select, textarea {
391 | font-size: 13pt;
392 | }
393 |
394 | /* BG */
395 |
396 | @include bg(_misc(bg-width));
397 |
398 | }
399 |
400 | /* Normal */
401 |
402 | @include breakpoint('<=normal') {
403 |
404 | /* Basic */
405 |
406 | body, input, select, textarea {
407 | font-size: 12pt;
408 | }
409 |
410 | /* BG */
411 |
412 | @include bg(_misc(bg-width) * 0.5);
413 |
414 | }
415 |
416 | /* Mobile */
417 |
418 | @include breakpoint('<=mobile') {
419 |
420 | /* Basic */
421 |
422 | body {
423 | min-width: 320px;
424 | }
425 |
426 | body, input, select, textarea {
427 | font-size: 11pt;
428 | }
429 |
430 | /* BG */
431 |
432 | @include bg(_misc(bg-width) * 0.2);
433 |
434 | /* Header */
435 |
436 | #header {
437 | h1 {
438 | font-size: 2.5em;
439 | }
440 |
441 | p {
442 | font-size: 1em;
443 | }
444 |
445 | nav {
446 | font-size: 1em;
447 |
448 | a {
449 | &:hover {
450 | font-size: 1em;
451 | }
452 |
453 | &:active {
454 | font-size: 1em;
455 | }
456 | }
457 | }
458 | }
459 |
460 | }
461 |
462 | /* Mobile (Portrait) */
463 |
464 | @include breakpoint('<=mobilep') {
465 |
466 | /* BG */
467 |
468 | @include bg(_misc(bg-width) * 0.275);
469 |
470 | /* Header */
471 |
472 | #header {
473 | nav {
474 | padding: 0 1em;
475 | }
476 | }
477 |
478 | }
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Creative Commons Attribution 3.0 Unported
2 | http://creativecommons.org/licenses/by/3.0/
3 |
4 | License
5 |
6 | THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
7 |
8 | BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
9 |
10 | 1. Definitions
11 |
12 | 1. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
13 | 2. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License.
14 | 3. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.
15 | 4. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
16 | 5. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
17 | 6. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
18 | 7. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
19 | 8. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
20 | 9. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.
21 |
22 | 2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.
23 |
24 | 3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
25 |
26 | 1. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;
27 | 2. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";
28 | 3. to Distribute and Publicly Perform the Work including as incorporated in Collections; and,
29 | 4. to Distribute and Publicly Perform Adaptations.
30 | 5.
31 |
32 | For the avoidance of doubt:
33 | 1. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
34 | 2. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
35 | 3. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.
36 |
37 | The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.
38 |
39 | 4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
40 |
41 | 1. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(b), as requested.
42 | 2. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4 (b) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
43 | 3. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.
44 |
45 | 5. Representations, Warranties and Disclaimer
46 |
47 | UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
48 |
49 | 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
50 |
51 | 7. Termination
52 |
53 | 1. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
54 | 2. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
55 |
56 | 8. Miscellaneous
57 |
58 | 1. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
59 | 2. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
60 | 3. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
61 | 4. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
62 | 5. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
63 | 6. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.
64 |
--------------------------------------------------------------------------------
/assets/css/main.css:
--------------------------------------------------------------------------------
1 | @import url("fontawesome-all.min.css");
2 |
3 | /*
4 | Aerial by HTML5 UP
5 | html5up.net | @ajlkn
6 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
7 | */
8 |
9 | html, body, div, span, applet, object,
10 | iframe, h1, h2, h3, h4, h5, h6, p, blockquote,
11 | pre, a, abbr, acronym, address, big, cite,
12 | code, del, dfn, em, img, ins, kbd, q, s, samp,
13 | small, strike, strong, sub, sup, tt, var, b,
14 | u, i, center, dl, dt, dd, ol, ul, li, fieldset,
15 | form, label, legend, table, caption, tbody,
16 | tfoot, thead, tr, th, td, article, aside,
17 | canvas, details, embed, figure, figcaption,
18 | footer, header, hgroup, menu, nav, output, ruby,
19 | section, summary, time, mark, audio, video {
20 | margin: 0;
21 | padding: 0;
22 | border: 0;
23 | font-size: 100%;
24 | font: inherit;
25 | vertical-align: baseline;}
26 |
27 | article, aside, details, figcaption, figure,
28 | footer, header, hgroup, menu, nav, section {
29 | display: block;}
30 |
31 | body {
32 | line-height: 1;
33 | }
34 |
35 | ol, ul {
36 | list-style: none;
37 | }
38 |
39 | blockquote, q {
40 | quotes: none;
41 | }
42 |
43 | blockquote:before, blockquote:after, q:before, q:after {
44 | content: '';
45 | content: none;
46 | }
47 |
48 | table {
49 | border-collapse: collapse;
50 | border-spacing: 0;
51 | }
52 |
53 | body {
54 | -webkit-text-size-adjust: none;
55 | }
56 |
57 | mark {
58 | background-color: transparent;
59 | color: inherit;
60 | }
61 |
62 | input::-moz-focus-inner {
63 | border: 0;
64 | padding: 0;
65 | }
66 |
67 | input, select, textarea {
68 | -moz-appearance: none;
69 | -webkit-appearance: none;
70 | -ms-appearance: none;
71 | appearance: none;
72 | }
73 |
74 | /* Basic */
75 |
76 | html {
77 | box-sizing: border-box;
78 | }
79 |
80 | *, *:before, *:after {
81 | box-sizing: inherit;
82 | }
83 |
84 | body {
85 | background: #fff;
86 | overflow: hidden;
87 | }
88 |
89 | body.is-preload *, body.is-preload *:before, body.is-preload *:after {
90 | -moz-animation: none !important;
91 | -webkit-animation: none !important;
92 | -ms-animation: none !important;
93 | animation: none !important;
94 | -moz-transition: none !important;
95 | -webkit-transition: none !important;
96 | -ms-transition: none !important;
97 | transition: none !important;
98 | }
99 |
100 | body, input, select, textarea {
101 | color: #fff;
102 | font-family: sans-serif;
103 | font-size: 15pt;
104 | font-weight: 300 !important;
105 | letter-spacing: -0.025em;
106 | line-height: 1.75em;
107 | }
108 |
109 | a {
110 | -moz-transition: border-color 0.2s ease-in-out;
111 | -webkit-transition: border-color 0.2s ease-in-out;
112 | -ms-transition: border-color 0.2s ease-in-out;
113 | transition: border-color 0.2s ease-in-out;
114 | border-bottom: dotted 1px;
115 | color: inherit;
116 | outline: 0;
117 | text-decoration: none;
118 | }
119 |
120 | a:hover {
121 | border-color: transparent;
122 | }
123 |
124 | /* Icon */
125 |
126 | .icon {
127 | text-decoration: none;
128 | position: relative;
129 | }
130 |
131 | .icon:before {
132 | -moz-osx-font-smoothing: grayscale;
133 | -webkit-font-smoothing: antialiased;
134 | display: inline-block;
135 | font-style: normal;
136 | font-variant: normal;
137 | text-rendering: auto;
138 | line-height: 1;
139 | text-transform: none !important;
140 | font-family: 'Font Awesome 5 Free';
141 | font-weight: 400;
142 | }
143 |
144 | .icon > .label {
145 | display: none;
146 | }
147 |
148 | .icon.solid:before {
149 | font-weight: 900;
150 | }
151 |
152 | .icon.brands:before {
153 | font-family: 'Font Awesome 5 Brands';
154 | }
155 |
156 | /* Wrapper */
157 |
158 | @-moz-keyframes wrapper {
159 | 0% {
160 | opacity: 0;
161 | }
162 |
163 | 100% {
164 | opacity: 1;
165 | }
166 | }
167 |
168 | @-webkit-keyframes wrapper {
169 | 0% {
170 | opacity: 0;
171 | }
172 |
173 | 100% {
174 | opacity: 1;
175 | }
176 | }
177 |
178 | @-ms-keyframes wrapper {
179 | 0% {
180 | opacity: 0;
181 | }
182 |
183 | 100% {
184 | opacity: 1;
185 | }
186 | }
187 |
188 | @keyframes wrapper {
189 | 0% {
190 | opacity: 0;
191 | }
192 |
193 | 100% {
194 | opacity: 1;
195 | }
196 | }
197 |
198 | #wrapper {
199 | -moz-animation: wrapper 3s forwards;
200 | -webkit-animation: wrapper 3s forwards;
201 | -ms-animation: wrapper 3s forwards;
202 | animation: wrapper 3s forwards;
203 | height: 100%;
204 | left: 0;
205 | opacity: 0;
206 | position: fixed;
207 | top: 0;
208 | width: 100%;
209 | }
210 |
211 | /* BG */
212 |
213 | #bg {
214 | -moz-animation: bg 60s linear infinite;
215 | -webkit-animation: bg 60s linear infinite;
216 | -ms-animation: bg 60s linear infinite;
217 | animation: bg 60s linear infinite;
218 | -moz-backface-visibility: hidden;
219 | -webkit-backface-visibility: hidden;
220 | -ms-backface-visibility: hidden;
221 | backface-visibility: hidden;
222 | -moz-transform: translate3d(0,0,0);
223 | -webkit-transform: translate3d(0,0,0);
224 | -ms-transform: translate3d(0,0,0);
225 | transform: translate3d(0,0,0);
226 | /* Set your background with this */
227 |
228 | background: #348cb2 url("images/bg.jpg") bottom left;
229 | background-repeat: repeat-x;
230 | height: 100%;
231 | left: 0;
232 | opacity: 1;
233 | position: fixed;
234 | top: 0;
235 | }
236 |
237 | @-moz-keyframes bg {
238 | 0% {
239 | -moz-transform: translate3d(0,0,0);
240 | -webkit-transform: translate3d(0,0,0);
241 | -ms-transform: translate3d(0,0,0);
242 | transform: translate3d(0,0,0);
243 | }
244 |
245 | 100% {
246 | -moz-transform: translate3d(-2250px,0,0);
247 | -webkit-transform: translate3d(-2250px,0,0);
248 | -ms-transform: translate3d(-2250px,0,0);
249 | transform: translate3d(-2250px,0,0);
250 | }
251 | }
252 |
253 | @-webkit-keyframes bg {
254 | 0% {
255 | -moz-transform: translate3d(0,0,0);
256 | -webkit-transform: translate3d(0,0,0);
257 | -ms-transform: translate3d(0,0,0);
258 | transform: translate3d(0,0,0);
259 | }
260 |
261 | 100% {
262 | -moz-transform: translate3d(-2250px,0,0);
263 | -webkit-transform: translate3d(-2250px,0,0);
264 | -ms-transform: translate3d(-2250px,0,0);
265 | transform: translate3d(-2250px,0,0);
266 | }
267 | }
268 |
269 | @-ms-keyframes bg {
270 | 0% {
271 | -moz-transform: translate3d(0,0,0);
272 | -webkit-transform: translate3d(0,0,0);
273 | -ms-transform: translate3d(0,0,0);
274 | transform: translate3d(0,0,0);
275 | }
276 |
277 | 100% {
278 | -moz-transform: translate3d(-2250px,0,0);
279 | -webkit-transform: translate3d(-2250px,0,0);
280 | -ms-transform: translate3d(-2250px,0,0);
281 | transform: translate3d(-2250px,0,0);
282 | }
283 | }
284 |
285 | @keyframes bg {
286 | 0% {
287 | -moz-transform: translate3d(0,0,0);
288 | -webkit-transform: translate3d(0,0,0);
289 | -ms-transform: translate3d(0,0,0);
290 | transform: translate3d(0,0,0);
291 | }
292 |
293 | 100% {
294 | -moz-transform: translate3d(-2250px,0,0);
295 | -webkit-transform: translate3d(-2250px,0,0);
296 | -ms-transform: translate3d(-2250px,0,0);
297 | transform: translate3d(-2250px,0,0);
298 | }
299 | }
300 |
301 | #bg {
302 | background-size: 2250px auto;
303 | width: 6750px;
304 | }
305 |
306 | /* Overlay */
307 |
308 | @-moz-keyframes overlay {
309 | 0% {
310 | opacity: 0;
311 | }
312 |
313 | 100% {
314 | opacity: 1;
315 | }
316 | }
317 |
318 | @-webkit-keyframes overlay {
319 | 0% {
320 | opacity: 0;
321 | }
322 |
323 | 100% {
324 | opacity: 1;
325 | }
326 | }
327 |
328 | @-ms-keyframes overlay {
329 | 0% {
330 | opacity: 0;
331 | }
332 |
333 | 100% {
334 | opacity: 1;
335 | }
336 | }
337 |
338 | @keyframes overlay {
339 | 0% {
340 | opacity: 0;
341 | }
342 |
343 | 100% {
344 | opacity: 1;
345 | }
346 | }
347 |
348 | #overlay {
349 | -moz-animation: overlay 1.5s 1.5s forwards;
350 | -webkit-animation: overlay 1.5s 1.5s forwards;
351 | -ms-animation: overlay 1.5s 1.5s forwards;
352 | animation: overlay 1.5s 1.5s forwards;
353 | background-attachment: fixed, fixed;
354 | background-image: url("images/overlay-pattern.png"), url("images/overlay.svg");
355 | background-position: top left, center center;
356 | background-repeat: repeat, no-repeat;
357 | background-size: auto, cover;
358 | height: 100%;
359 | left: 0;
360 | opacity: 0;
361 | position: fixed;
362 | top: 0;
363 | width: 100%;
364 | }
365 |
366 | /* Main */
367 |
368 | #main {
369 | height: 100%;
370 | left: 0;
371 | position: fixed;
372 | text-align: center;
373 | top: 0;
374 | width: 100%;
375 | }
376 |
377 | #main:before {
378 | content: '';
379 | display: inline-block;
380 | height: 100%;
381 | margin-right: 0;
382 | vertical-align: middle;
383 | width: 1px;
384 | }
385 |
386 | /* Header */
387 |
388 | @-moz-keyframes header {
389 | 0% {
390 | -moz-transform: translate3d(0,1em,0);
391 | -webkit-transform: translate3d(0,1em,0);
392 | -ms-transform: translate3d(0,1em,0);
393 | transform: translate3d(0,1em,0);
394 | opacity: 0;
395 | }
396 |
397 | 100% {
398 | -moz-transform: translate3d(0,0,0);
399 | -webkit-transform: translate3d(0,0,0);
400 | -ms-transform: translate3d(0,0,0);
401 | transform: translate3d(0,0,0);
402 | opacity: 1;
403 | }
404 | }
405 |
406 | @-webkit-keyframes header {
407 | 0% {
408 | -moz-transform: translate3d(0,1em,0);
409 | -webkit-transform: translate3d(0,1em,0);
410 | -ms-transform: translate3d(0,1em,0);
411 | transform: translate3d(0,1em,0);
412 | opacity: 0;
413 | }
414 |
415 | 100% {
416 | -moz-transform: translate3d(0,0,0);
417 | -webkit-transform: translate3d(0,0,0);
418 | -ms-transform: translate3d(0,0,0);
419 | transform: translate3d(0,0,0);
420 | opacity: 1;
421 | }
422 | }
423 |
424 | @-ms-keyframes header {
425 | 0% {
426 | -moz-transform: translate3d(0,1em,0);
427 | -webkit-transform: translate3d(0,1em,0);
428 | -ms-transform: translate3d(0,1em,0);
429 | transform: translate3d(0,1em,0);
430 | opacity: 0;
431 | }
432 |
433 | 100% {
434 | -moz-transform: translate3d(0,0,0);
435 | -webkit-transform: translate3d(0,0,0);
436 | -ms-transform: translate3d(0,0,0);
437 | transform: translate3d(0,0,0);
438 | opacity: 1;
439 | }
440 | }
441 |
442 | @keyframes header {
443 | 0% {
444 | -moz-transform: translate3d(0,1em,0);
445 | -webkit-transform: translate3d(0,1em,0);
446 | -ms-transform: translate3d(0,1em,0);
447 | transform: translate3d(0,1em,0);
448 | opacity: 0;
449 | }
450 |
451 | 100% {
452 | -moz-transform: translate3d(0,0,0);
453 | -webkit-transform: translate3d(0,0,0);
454 | -ms-transform: translate3d(0,0,0);
455 | transform: translate3d(0,0,0);
456 | opacity: 1;
457 | }
458 | }
459 |
460 | @-moz-keyframes nav-icons {
461 | 0% {
462 | -moz-transform: translate3d(0,1em,0);
463 | -webkit-transform: translate3d(0,1em,0);
464 | -ms-transform: translate3d(0,1em,0);
465 | transform: translate3d(0,1em,0);
466 | opacity: 0;
467 | }
468 |
469 | 100% {
470 | -moz-transform: translate3d(0,0,0);
471 | -webkit-transform: translate3d(0,0,0);
472 | -ms-transform: translate3d(0,0,0);
473 | transform: translate3d(0,0,0);
474 | opacity: 1;
475 | }
476 | }
477 |
478 | @-webkit-keyframes nav-icons {
479 | 0% {
480 | -moz-transform: translate3d(0,1em,0);
481 | -webkit-transform: translate3d(0,1em,0);
482 | -ms-transform: translate3d(0,1em,0);
483 | transform: translate3d(0,1em,0);
484 | opacity: 0;
485 | }
486 |
487 | 100% {
488 | -moz-transform: translate3d(0,0,0);
489 | -webkit-transform: translate3d(0,0,0);
490 | -ms-transform: translate3d(0,0,0);
491 | transform: translate3d(0,0,0);
492 | opacity: 1;
493 | }
494 | }
495 |
496 | @-ms-keyframes nav-icons {
497 | 0% {
498 | -moz-transform: translate3d(0,1em,0);
499 | -webkit-transform: translate3d(0,1em,0);
500 | -ms-transform: translate3d(0,1em,0);
501 | transform: translate3d(0,1em,0);
502 | opacity: 0;
503 | }
504 |
505 | 100% {
506 | -moz-transform: translate3d(0,0,0);
507 | -webkit-transform: translate3d(0,0,0);
508 | -ms-transform: translate3d(0,0,0);
509 | transform: translate3d(0,0,0);
510 | opacity: 1;
511 | }
512 | }
513 |
514 | @keyframes nav-icons {
515 | 0% {
516 | -moz-transform: translate3d(0,1em,0);
517 | -webkit-transform: translate3d(0,1em,0);
518 | -ms-transform: translate3d(0,1em,0);
519 | transform: translate3d(0,1em,0);
520 | opacity: 0;
521 | }
522 |
523 | 100% {
524 | -moz-transform: translate3d(0,0,0);
525 | -webkit-transform: translate3d(0,0,0);
526 | -ms-transform: translate3d(0,0,0);
527 | transform: translate3d(0,0,0);
528 | opacity: 1;
529 | }
530 | }
531 |
532 | #header {
533 | -moz-animation: header 1s 2.25s forwards;
534 | -webkit-animation: header 1s 2.25s forwards;
535 | -ms-animation: header 1s 2.25s forwards;
536 | animation: header 1s 2.25s forwards;
537 | -moz-backface-visibility: hidden;
538 | -webkit-backface-visibility: hidden;
539 | -ms-backface-visibility: hidden;
540 | backface-visibility: hidden;
541 | -moz-transform: translate3d(0,0,0);
542 | -webkit-transform: translate3d(0,0,0);
543 | -ms-transform: translate3d(0,0,0);
544 | transform: translate3d(0,0,0);
545 | cursor: default;
546 | display: inline-block;
547 | opacity: 0;
548 | position: relative;
549 | text-align: center;
550 | top: -1em;
551 | vertical-align: middle;
552 | width: 90%;
553 | }
554 |
555 | #header h1 {
556 | font-size: 4.35em;
557 | font-weight: 900;
558 | letter-spacing: -0.035em;
559 | line-height: 1em;
560 | }
561 |
562 | #header p {
563 | font-size: 1.25em;
564 | margin: 0.75em 0 0.25em 0;
565 | opacity: 0.75;
566 | }
567 |
568 | #header nav {
569 | margin: 1.5em 0 0 0;
570 | }
571 |
572 | #header nav li {
573 | -moz-animation: nav-icons 0.5s ease-in-out forwards;
574 | -webkit-animation: nav-icons 0.5s ease-in-out forwards;
575 | -ms-animation: nav-icons 0.5s ease-in-out forwards;
576 | animation: nav-icons 0.5s ease-in-out forwards;
577 | -moz-backface-visibility: hidden;
578 | -webkit-backface-visibility: hidden;
579 | -ms-backface-visibility: hidden;
580 | backface-visibility: hidden;
581 | -moz-transform: translate3d(0,0,0);
582 | -webkit-transform: translate3d(0,0,0);
583 | -ms-transform: translate3d(0,0,0);
584 | transform: translate3d(0,0,0);
585 | display: inline-block;
586 | height: 5.35em;
587 | line-height: 5.885em;
588 | opacity: 0;
589 | position: relative;
590 | top: 0;
591 | width: 5.35em;
592 | }
593 |
594 | #header nav li:nth-child(1) {
595 | -moz-animation-delay: 2.5s;
596 | -webkit-animation-delay: 2.5s;
597 | -ms-animation-delay: 2.5s;
598 | animation-delay: 2.5s;
599 | }
600 |
601 | #header nav li:nth-child(2) {
602 | -moz-animation-delay: 2.75s;
603 | -webkit-animation-delay: 2.75s;
604 | -ms-animation-delay: 2.75s;
605 | animation-delay: 2.75s;
606 | }
607 |
608 | #header nav li:nth-child(3) {
609 | -moz-animation-delay: 3s;
610 | -webkit-animation-delay: 3s;
611 | -ms-animation-delay: 3s;
612 | animation-delay: 3s;
613 | }
614 |
615 | #header nav li:nth-child(4) {
616 | -moz-animation-delay: 3.25s;
617 | -webkit-animation-delay: 3.25s;
618 | -ms-animation-delay: 3.25s;
619 | animation-delay: 3.25s;
620 | }
621 |
622 | #header nav li:nth-child(5) {
623 | -moz-animation-delay: 3.5s;
624 | -webkit-animation-delay: 3.5s;
625 | -ms-animation-delay: 3.5s;
626 | animation-delay: 3.5s;
627 | }
628 |
629 | #header nav li:nth-child(6) {
630 | -moz-animation-delay: 3.75s;
631 | -webkit-animation-delay: 3.75s;
632 | -ms-animation-delay: 3.75s;
633 | animation-delay: 3.75s;
634 | }
635 |
636 | #header nav li:nth-child(7) {
637 | -moz-animation-delay: 4s;
638 | -webkit-animation-delay: 4s;
639 | -ms-animation-delay: 4s;
640 | animation-delay: 4s;
641 | }
642 |
643 | #header nav li:nth-child(8) {
644 | -moz-animation-delay: 4.25s;
645 | -webkit-animation-delay: 4.25s;
646 | -ms-animation-delay: 4.25s;
647 | animation-delay: 4.25s;
648 | }
649 |
650 | #header nav li:nth-child(9) {
651 | -moz-animation-delay: 4.5s;
652 | -webkit-animation-delay: 4.5s;
653 | -ms-animation-delay: 4.5s;
654 | animation-delay: 4.5s;
655 | }
656 |
657 | #header nav li:nth-child(10) {
658 | -moz-animation-delay: 4.75s;
659 | -webkit-animation-delay: 4.75s;
660 | -ms-animation-delay: 4.75s;
661 | animation-delay: 4.75s;
662 | }
663 |
664 | #header nav a {
665 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
666 | -webkit-touch-callout: none;
667 | border: 0;
668 | display: inline-block;
669 | }
670 |
671 | #header nav a:before {
672 | -moz-transition: all 0.2s ease-in-out;
673 | -webkit-transition: all 0.2s ease-in-out;
674 | -ms-transition: all 0.2s ease-in-out;
675 | transition: all 0.2s ease-in-out;
676 | border-radius: 100%;
677 | border: solid 1px #fff;
678 | display: block;
679 | font-size: 1.75em;
680 | height: 2.5em;
681 | line-height: 2.5em;
682 | position: relative;
683 | text-align: center;
684 | top: 0;
685 | width: 2.5em;
686 | }
687 |
688 | #header nav a:hover {
689 | font-size: 1.1em;
690 | }
691 |
692 | #header nav a:hover:before {
693 | background-color: rgba(255, 255, 255, 0.175);
694 | color: #fff;
695 | }
696 |
697 | #header nav a:active {
698 | font-size: 0.95em;
699 | background: none;
700 | }
701 |
702 | #header nav a:active:before {
703 | background-color: rgba(255, 255, 255, 0.35);
704 | color: #fff;
705 | }
706 |
707 | #header nav a span {
708 | display: none;
709 | }
710 |
711 | /* Footer */
712 |
713 | #footer {
714 | background-image: -moz-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,0.5) 75%);
715 | background-image: -webkit-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,0.5) 75%);
716 | background-image: -ms-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,0.5) 75%);
717 | background-image: linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,0.5) 75%);
718 | bottom: 0;
719 | cursor: default;
720 | height: 6em;
721 | left: 0;
722 | line-height: 8em;
723 | position: absolute;
724 | text-align: center;
725 | width: 100%;
726 | }
727 |
728 | /* Wide */
729 |
730 | @media screen and (max-width: 1680px) {
731 |
732 | /* Basic */
733 |
734 | body, input, select, textarea {
735 | font-size: 13pt;
736 | }
737 |
738 | /* BG */
739 |
740 | @-moz-keyframes bg {
741 | 0% {
742 | -moz-transform: translate3d(0,0,0);
743 | -webkit-transform: translate3d(0,0,0);
744 | -ms-transform: translate3d(0,0,0);
745 | transform: translate3d(0,0,0);
746 | }
747 |
748 | 100% {
749 | -moz-transform: translate3d(-1500px,0,0);
750 | -webkit-transform: translate3d(-1500px,0,0);
751 | -ms-transform: translate3d(-1500px,0,0);
752 | transform: translate3d(-1500px,0,0);
753 | }
754 |
755 | }
756 |
757 | @-webkit-keyframes bg {
758 | 0% {
759 | -moz-transform: translate3d(0,0,0);
760 | -webkit-transform: translate3d(0,0,0);
761 | -ms-transform: translate3d(0,0,0);
762 | transform: translate3d(0,0,0);
763 | }
764 |
765 | 100% {
766 | -moz-transform: translate3d(-1500px,0,0);
767 | -webkit-transform: translate3d(-1500px,0,0);
768 | -ms-transform: translate3d(-1500px,0,0);
769 | transform: translate3d(-1500px,0,0);
770 | }
771 | }
772 |
773 | @-ms-keyframes bg {
774 | 0% {
775 | -moz-transform: translate3d(0,0,0);
776 | -webkit-transform: translate3d(0,0,0);
777 | -ms-transform: translate3d(0,0,0);
778 | transform: translate3d(0,0,0);
779 | }
780 |
781 | 100% {
782 | -moz-transform: translate3d(-1500px,0,0);
783 | -webkit-transform: translate3d(-1500px,0,0);
784 | -ms-transform: translate3d(-1500px,0,0);
785 | transform: translate3d(-1500px,0,0);
786 | }
787 | }
788 |
789 | @keyframes bg {
790 | 0% {
791 | -moz-transform: translate3d(0,0,0);
792 | -webkit-transform: translate3d(0,0,0);
793 | -ms-transform: translate3d(0,0,0);
794 | transform: translate3d(0,0,0);
795 | }
796 |
797 | 100% {
798 | -moz-transform: translate3d(-1500px,0,0);
799 | -webkit-transform: translate3d(-1500px,0,0);
800 | -ms-transform: translate3d(-1500px,0,0);
801 | transform: translate3d(-1500px,0,0);
802 | }
803 | }
804 |
805 | #bg {
806 | background-size: 1500px auto;
807 | width: 4500px;
808 | } }
809 |
810 | /* Normal */
811 |
812 | @media screen and (max-width: 1280px) {
813 |
814 | /* Basic */
815 |
816 | body, input, select, textarea {
817 | font-size: 12pt;
818 | }
819 |
820 | /* BG */
821 |
822 | @-moz-keyframes bg {
823 | 0% {
824 | -moz-transform: translate3d(0,0,0);
825 | -webkit-transform: translate3d(0,0,0);
826 | -ms-transform: translate3d(0,0,0);
827 | transform: translate3d(0,0,0);
828 | }
829 |
830 | 100% {
831 | -moz-transform: translate3d(-750px,0,0);
832 | -webkit-transform: translate3d(-750px,0,0);
833 | -ms-transform: translate3d(-750px,0,0);
834 | transform: translate3d(-750px,0,0);
835 | }
836 |
837 | }
838 |
839 | @-webkit-keyframes bg {
840 | 0% {
841 | -moz-transform: translate3d(0,0,0);
842 | -webkit-transform: translate3d(0,0,0);
843 | -ms-transform: translate3d(0,0,0);
844 | transform: translate3d(0,0,0);
845 | }
846 |
847 | 100% {
848 | -moz-transform: translate3d(-750px,0,0);
849 | -webkit-transform: translate3d(-750px,0,0);
850 | -ms-transform: translate3d(-750px,0,0);
851 | transform: translate3d(-750px,0,0);
852 | }
853 | }
854 |
855 | @-ms-keyframes bg {
856 | 0% {
857 | -moz-transform: translate3d(0,0,0);
858 | -webkit-transform: translate3d(0,0,0);
859 | -ms-transform: translate3d(0,0,0);
860 | transform: translate3d(0,0,0);
861 | }
862 |
863 | 100% {
864 | -moz-transform: translate3d(-750px,0,0);
865 | -webkit-transform: translate3d(-750px,0,0);
866 | -ms-transform: translate3d(-750px,0,0);
867 | transform: translate3d(-750px,0,0);
868 | }
869 | }
870 |
871 | @keyframes bg {
872 | 0% {
873 | -moz-transform: translate3d(0,0,0);
874 | -webkit-transform: translate3d(0,0,0);
875 | -ms-transform: translate3d(0,0,0);
876 | transform: translate3d(0,0,0);
877 | }
878 |
879 | 100% {
880 | -moz-transform: translate3d(-750px,0,0);
881 | -webkit-transform: translate3d(-750px,0,0);
882 | -ms-transform: translate3d(-750px,0,0);
883 | transform: translate3d(-750px,0,0);
884 | }
885 | }
886 |
887 | #bg {
888 | background-size: 750px auto;
889 | width: 2250px;
890 | } }
891 |
892 | /* Mobile */
893 |
894 | @media screen and (max-width: 736px) {
895 |
896 | /* Basic */
897 |
898 | body {
899 | min-width: 320px;
900 | }
901 |
902 | body, input, select, textarea {
903 | font-size: 11pt;
904 | }
905 |
906 | /* BG */
907 |
908 | @-moz-keyframes bg {
909 | 0% {
910 | -moz-transform: translate3d(0,0,0);
911 | -webkit-transform: translate3d(0,0,0);
912 | -ms-transform: translate3d(0,0,0);
913 | transform: translate3d(0,0,0);
914 | }
915 |
916 | 100% {
917 | -moz-transform: translate3d(-300px,0,0);
918 | -webkit-transform: translate3d(-300px,0,0);
919 | -ms-transform: translate3d(-300px,0,0);
920 | transform: translate3d(-300px,0,0);
921 | }
922 |
923 | }
924 |
925 | @-webkit-keyframes bg {
926 | 0% {
927 | -moz-transform: translate3d(0,0,0);
928 | -webkit-transform: translate3d(0,0,0);
929 | -ms-transform: translate3d(0,0,0);
930 | transform: translate3d(0,0,0);
931 | }
932 |
933 | 100% {
934 | -moz-transform: translate3d(-300px,0,0);
935 | -webkit-transform: translate3d(-300px,0,0);
936 | -ms-transform: translate3d(-300px,0,0);
937 | transform: translate3d(-300px,0,0);
938 | }
939 | }
940 |
941 | @-ms-keyframes bg {
942 | 0% {
943 | -moz-transform: translate3d(0,0,0);
944 | -webkit-transform: translate3d(0,0,0);
945 | -ms-transform: translate3d(0,0,0);
946 | transform: translate3d(0,0,0);
947 | }
948 |
949 | 100% {
950 | -moz-transform: translate3d(-300px,0,0);
951 | -webkit-transform: translate3d(-300px,0,0);
952 | -ms-transform: translate3d(-300px,0,0);
953 | transform: translate3d(-300px,0,0);
954 | }
955 | }
956 |
957 | @keyframes bg {
958 | 0% {
959 | -moz-transform: translate3d(0,0,0);
960 | -webkit-transform: translate3d(0,0,0);
961 | -ms-transform: translate3d(0,0,0);
962 | transform: translate3d(0,0,0);
963 | }
964 |
965 | 100% {
966 | -moz-transform: translate3d(-300px,0,0);
967 | -webkit-transform: translate3d(-300px,0,0);
968 | -ms-transform: translate3d(-300px,0,0);
969 | transform: translate3d(-300px,0,0);
970 | }
971 | }
972 |
973 | #bg {
974 | background-size: 300px auto;
975 | width: 900px;
976 | }
977 |
978 | /* Header */
979 |
980 | #header h1 {
981 | font-size: 2.5em;
982 | }
983 |
984 | #header p {
985 | font-size: 1em;
986 | }
987 |
988 | #header nav {
989 | font-size: 1em;
990 | }
991 |
992 | #header nav a:hover {
993 | font-size: 1em;
994 | }
995 |
996 | #header nav a:active {
997 | font-size: 1em;
998 | } }
999 |
1000 | /* Mobile (Portrait) */
1001 |
1002 | @media screen and (max-width: 480px) {
1003 |
1004 | /* BG */
1005 |
1006 | @-moz-keyframes bg {
1007 | 0% {
1008 | -moz-transform: translate3d(0,0,0);
1009 | -webkit-transform: translate3d(0,0,0);
1010 | -ms-transform: translate3d(0,0,0);
1011 | transform: translate3d(0,0,0);
1012 | }
1013 |
1014 | 100% {
1015 | -moz-transform: translate3d(-412.5px,0,0);
1016 | -webkit-transform: translate3d(-412.5px,0,0);
1017 | -ms-transform: translate3d(-412.5px,0,0);
1018 | transform: translate3d(-412.5px,0,0);
1019 | }
1020 |
1021 | }
1022 |
1023 | @-webkit-keyframes bg {
1024 | 0% {
1025 | -moz-transform: translate3d(0,0,0);
1026 | -webkit-transform: translate3d(0,0,0);
1027 | -ms-transform: translate3d(0,0,0);
1028 | transform: translate3d(0,0,0);
1029 | }
1030 |
1031 | 100% {
1032 | -moz-transform: translate3d(-412.5px,0,0);
1033 | -webkit-transform: translate3d(-412.5px,0,0);
1034 | -ms-transform: translate3d(-412.5px,0,0);
1035 | transform: translate3d(-412.5px,0,0);
1036 | }
1037 | }
1038 |
1039 | @-ms-keyframes bg {
1040 | 0% {
1041 | -moz-transform: translate3d(0,0,0);
1042 | -webkit-transform: translate3d(0,0,0);
1043 | -ms-transform: translate3d(0,0,0);
1044 | transform: translate3d(0,0,0);
1045 | }
1046 |
1047 | 100% {
1048 | -moz-transform: translate3d(-412.5px,0,0);
1049 | -webkit-transform: translate3d(-412.5px,0,0);
1050 | -ms-transform: translate3d(-412.5px,0,0);
1051 | transform: translate3d(-412.5px,0,0);
1052 | }
1053 | }
1054 |
1055 | @keyframes bg {
1056 | 0% {
1057 | -moz-transform: translate3d(0,0,0);
1058 | -webkit-transform: translate3d(0,0,0);
1059 | -ms-transform: translate3d(0,0,0);
1060 | transform: translate3d(0,0,0);
1061 | }
1062 |
1063 | 100% {
1064 | -moz-transform: translate3d(-412.5px,0,0);
1065 | -webkit-transform: translate3d(-412.5px,0,0);
1066 | -ms-transform: translate3d(-412.5px,0,0);
1067 | transform: translate3d(-412.5px,0,0);
1068 | }
1069 | }
1070 |
1071 | #bg {
1072 | background-size: 412.5px auto;
1073 | width: 1237.5px;
1074 | }
1075 |
1076 | /* Header */
1077 |
1078 | #header nav {
1079 | padding: 0 1em;
1080 | } }
--------------------------------------------------------------------------------
/assets/css/fontawesome-all.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | */
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | .fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudflare:before{content:"\e07d"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-faucet:before{content:"\e005"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guilded:before{content:"\e07e"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-hands-wash:before{content:"\e05e"}.fa-handshake:before{content:"\f2b5"}.fa-handshake-alt-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hive:before{content:"\e07f"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-house-user:before{content:"\e065"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\e013"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-innosoft:before{content:"\e080"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-instalod:before{content:"\e081"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-house:before{content:"\e066"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\e01a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-octopus-deploy:before{content:"\e082"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-arrows:before{content:"\e068"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-perbyte:before{content:"\e083"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\e069"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-rust:before{content:"\e07a"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopify:before{content:"\e057"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sink:before{content:"\e06d"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-store-alt-slash:before{content:"\e070"}.fa-store-slash:before{content:"\e071"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-tiktok:before{content:"\e07b"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-uncharted:before{content:"\e084"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-users-slash:before{content:"\e073"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-vest:before{content:"\e085"}.fa-vest-patches:before{content:"\e086"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-virus:before{content:"\e074"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-watchman-monitoring:before{content:"\e087"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wodu:before{content:"\e088"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.fab,.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900}
--------------------------------------------------------------------------------
/myths-about-urandom/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Myths about /dev/urandom
8 |
24 |
25 |
26 |
27 |
28 |
Myths about /dev/urandom
29 |
30 |
38 |
There are a few things about /dev/urandom and /dev/random that are
39 | repeated again and again. Still they are false.
40 |
44 |
/dev/urandom is insecure. Always use /dev/random for cryptographic
45 | purposes.
46 |
Fact: /dev/urandom is the preferred source of cryptographic
47 | randomness on UNIX-like systems.
48 |
/dev/urandom is a pseudo random number generator, a PRNG, while
49 | /dev/random is a “true” random number generator.
50 |
Fact: Both
51 | /dev/urandom and /dev/random are using the exact same CSPRNG (a
52 | cryptographically secure pseudorandom number generator). They only
53 | differ in very few ways that have nothing to do with “true”
54 | randomness.
55 |
/dev/random is unambiguously the better choice for cryptography. Even
56 | if /dev/urandom were comparably secure, there’s no reason to choose the
57 | latter.
58 |
Fact: /dev/random has a very
59 | nasty problem: it blocks.
60 |
But that’s good! /dev/random gives out exactly as much randomness as
61 | it has entropy in its pool. /dev/urandom will give you insecure random
62 | numbers, even though it has long run out of entropy.
63 |
Fact: No. Even
64 | disregarding issues like availability and subsequent manipulation by
65 | users, the issue of entropy “running low” is a straw man. About 256 bits
66 | of entropy are enough to get computationally secure numbers for a long,
67 | long time.
68 |
And the fun only starts here: how does /dev/random know how much
69 | entropy there is available to give out? Stay tuned!
70 |
But cryptographers always talk about constant re-seeding. Doesn’t
71 | that contradict your last point?
72 |
Fact: You got me! Kind of. It is true, the
73 | random number generator is constantly re-seeded using whatever entropy
74 | the system can lay its hands on. But that has (partly) other
75 | reasons.
76 |
Look, I don’t claim that injecting entropy is bad. It’s good. I just
77 | claim that it’s bad to block when the entropy estimate is low.
78 |
That’s all good and nice, but even the man page for /dev/(u)random
79 | contradicts you! Does anyone who knows about this stuff actually agree
80 | with you?
81 |
Fact: No, it really
82 | doesn’t. It seems to imply that /dev/urandom is insecure for
83 | cryptographic use, unless you really understand all that cryptographic
84 | jargon.
85 |
The man page does recommend the use of /dev/random in some cases (it
86 | doesn’t hurt, in my opinion, but is not strictly necessary), but it also
87 | recommends /dev/urandom as the device to use for “normal” cryptographic
88 | use.
89 |
And while appeal to authority is usually nothing to be proud of, in
90 | cryptographic issues you’re generally right to be careful and try to get
91 | the opinion of a domain expert.
92 |
And yes, quite a few experts share my view
93 | that /dev/urandom is the go-to solution for your random number needs in
94 | a cryptography context on UNIX-like systems. Obviously, their opinions
95 | influenced mine, not the other way around.
96 |
Hard to believe, right? I must certainly be wrong! Well, read on and
97 | let me try to convince you.
98 |
I tried to keep it out, but I fear there are two preliminaries to be
99 | taken care of, before we can really tackle all those points.
100 |
Namely, what is randomness, or better:
101 | what kind of randomness am I talking about here?
102 |
And, even more important, I’m really not being condescending. I have
103 | written this document to have a thing to point to, when this discussion
104 | comes up again. More than 140 characters. Without repeating myself again
105 | and again. Being able to hone the writing and the arguments itself,
106 | benefitting many discussions in many venues.
107 |
And I’m certainly willing to hear differing opinions. I’m just saying
108 | that it won’t be enough to state that /dev/urandom is bad. You need to
109 | identify the points you’re disagreeing with and engage them.
110 |
You’re saying I’m stupid!
111 |
Emphatically no!
112 |
Actually, I used to believe that /dev/urandom was insecure myself, a
113 | few years ago. And it’s something you and I almost had to believe,
114 | because all those highly respected people on Usenet, in web forums and
115 | today on Twitter told us. Even the man page seems to say so. Who were we
116 | to dismiss their convincing argument about “entropy running low”?
117 |
This misconception isn’t so rampant because people are stupid, it is
118 | because with a little knowledge about cryptography (namely some vague
119 | idea what entropy is) it’s very easy to be convinced of it. Intuition
120 | almost forces us there. Unfortunately, intuition is often wrong in
121 | cryptography. So it is here.
122 |
True randomness
123 |
What does it mean for random numbers to be “truly random”?
124 |
I don’t want to dive into that issue too deep, because it quickly
125 | gets philosophical. Discussions have been known to unravel quickly,
126 | because everyone can wax about their favorite model of randomness,
127 | without paying attention to anyone else. Or even making himself
128 | understood.
129 |
I believe that the “gold standard” for “true randomness” are quantum
130 | effects. Observe a photon pass through a semi-transparent mirror. Or
131 | not. Observe some radioactive material emit alpha particles. It’s the
132 | best idea we have when it comes to randomness in the world. Other people
133 | might reasonably believe that those effects aren’t truly random. Or even
134 | that there is no randomness in the world at all. Let a million flowers
135 | bloom.
136 |
Cryptographers often circumvent this philosophical debate by
137 | disregarding what it means for randomness to be “true”. They care about
138 | unpredictability. As long as nobody can get any information about the
139 | next random number, we’re fine. And when you’re talking about random
140 | numbers as a prerequisite in using cryptography, that’s what you should
141 | aim for, in my opinion.
142 |
Anyway, I don’t care much about those “philosophically secure” random
143 | numbers, as I like to think of your “true” random numbers.
144 |
Two kinds of security,
145 | one that matters
146 |
But let’s assume you’ve obtained those “true” random numbers. What
147 | are you going to do with them?
148 |
You print them out, frame them and hang them on your living-room
149 | wall, to revel in the beauty of a quantum universe? That’s great, and I
150 | certainly understand.
151 |
Wait, what? You’re using them? For cryptographic purposes? Well, that
152 | spoils everything, because now things get a bit ugly.
153 |
You see, your truly-random, quantum effect blessed random numbers are
154 | put into some less respectable, real-world tarnished algorithms.
155 |
Because almost all of the cryptographic algorithms we use do not hold
156 | up to information-theoretic security. They can “only” offer
157 | computational security. The two exceptions that come to my mind
158 | are Shamir’s Secret Sharing and the One-time pad. And while the first
159 | one may be a valid counterpoint (if you actually intend to use it), the
160 | latter is utterly impractical.
161 |
But all those algorithms you know about, AES, RSA, Diffie-Hellman,
162 | Elliptic curves, and all those crypto packages you’re using, OpenSSL,
163 | GnuTLS, Keyczar, your operating system’s crypto API, these are only
164 | computationally secure.
165 |
What’s the difference? While information-theoretically secure
166 | algorithms are secure, period, those other algorithms cannot guarantee
167 | security against an adversary with unlimited computational power who’s
168 | trying all possibilities for keys. We still use them because it would
169 | take all the computers in the world taken together longer than the
170 | universe has existed, so far. That’s the level of “insecurity” we’re
171 | talking about here.
172 |
Unless some clever guy breaks the algorithm itself, using much less
173 | computational power. Even computational power achievable today. That’s
174 | the big prize every cryptanalyst dreams about: breaking AES itself,
175 | breaking RSA itself and so on.
176 |
So now we’re at the point where you don’t trust the inner building
177 | blocks of the random number generator, insisting on “true randomness”
178 | instead of “pseudo randomness”. But then you’re using those “true”
179 | random numbers in algorithms that you so despise that you didn’t want
180 | them near your random number generator in the first place!
181 |
Truth is, when state-of-the-art hash algorithms are broken, or when
182 | state-of-the-art block ciphers are broken, it doesn’t matter that you
183 | get “philosophically insecure” random numbers because of them. You’ve
184 | got nothing left to securely use them for anyway.
185 |
So just use those computationally-secure random numbers for your
186 | computationally-secure algorithms. In other words: use /dev/urandom.
187 |
Structure of
188 | Linux’s random number generator
189 |
An incorrect view
190 |
Chances are, your idea of the kernel’s random number generator is
191 | something similar to this:
192 |
193 |
194 | Mythical structure of the kernel’s random
195 | number generator
196 |
197 |
“True randomness”, albeit possibly skewed and biased, enters the
198 | system and its entropy is precisely counted and immediately added to an
199 | internal entropy counter. After de-biasing and whitening it’s entering
200 | the kernel’s entropy pool, where both /dev/random and /dev/urandom get
201 | their random numbers from.
202 |
The “true” random number generator, /dev/random, takes those random
203 | numbers straight out of the pool, if the entropy count is sufficient for
204 | the number of requested numbers, decreasing the entropy counter, of
205 | course. If not, it blocks until new entropy has entered the system.
206 |
The important thing in this narrative is that /dev/random basically
207 | yields the numbers that have been input by those randomness sources
208 | outside, after only the necessary whitening. Nothing more, just pure
209 | randomness.
210 |
/dev/urandom, so the story goes, is doing the same thing. Except when
211 | there isn’t sufficient entropy in the system. In contrast to
212 | /dev/random, it does not block, but gets “low quality random” numbers
213 | from a pseudorandom number generator (conceded, a cryptographically
214 | secure one) that is running alongside the rest of the random number
215 | machinery. This CSPRNG is just seeded once (or maybe every now and then,
216 | it doesn’t matter) with “true randomness” from the randomness pool, but
217 | you can’t really trust it.
218 |
In this view, that seems to be in a lot of people’s minds when
219 | they’re talking about random numbers on Linux, avoiding /dev/urandom is
220 | plausible.
221 |
Because either there is enough entropy left, then you get the same
222 | you’d have gotten from /dev/random. Or there isn’t, then you get those
223 | low-quality random numbers from a CSPRNG that almost never saw
224 | high-entropy input.
225 |
Devilish, right? Unfortunately, also utterly wrong. In reality, the
226 | internal structure of the random number generator looks like this.
227 |
A better simplification
228 |
Before Linux 4.8
229 |
230 |
231 | Actual structure of the kernel’s random
232 | number generator before Linux 4.8
233 |
234 |
See the big difference? The CSPRNG is not running alongside the
235 | random number generator, filling in for those times when /dev/urandom
236 | wants to output something, but has nothing good to output. The CSPRNG is
237 | an integral part of the random number generation process. There is no
238 | /dev/random handing out “good and pure” random numbers straight from the
239 | whitener. Every randomness source’s input is thoroughly mixed and hashed
240 | inside the CSPRNG, before it emerges as random numbers, either via
241 | /dev/urandom or /dev/random.
242 |
253 |
Another important difference is that there is no entropy counting
254 | going on here, but estimation. The amount of entropy some source is
255 | giving you isn’t something obvious that you just get, along with the
256 | data. It has to be estimated. Please note that when your estimate is too
257 | optimistic, the dearly held property of /dev/random, that it’s only
258 | giving out as many random numbers as available entropy allows, is gone.
259 | Unfortunately, it’s hard to estimate the amount of entropy.
260 |
The Linux kernel uses only the arrival times of events to estimate
261 | their entropy. It does that by interpolating polynomials of those
262 | arrival times, to calculate “how surprising” the actual arrival time
263 | was, according to the model. Whether this polynomial interpolation model
264 | is the best way to estimate entropy is an interesting question. There is
265 | also the problem that internal hardware restrictions might influence
266 | those arrival times. The sampling rates of all kinds of hardware
267 | components may also play a role, because they directly influence the
268 | values and the granularity of those event arrival times.
269 |
In the end, to the best of our knowledge, the kernel’s entropy
270 | estimate is pretty good. Which means it’s conservative. People argue
271 | about how good it really is, but that issue is far above my head. Still,
272 | if you insist on never handing out random numbers that are not “backed”
273 | by sufficient entropy, you might be nervous here. I’m sleeping sound
274 | because I don’t care about the entropy estimate.
275 |
So to make one thing crystal clear: both /dev/random and /dev/urandom
276 | are fed by the same CSPRNG. Only the behavior when their respective pool
277 | runs out of entropy, according to some estimate, differs: /dev/random
278 | blocks, while /dev/urandom does not.
279 |
From Linux 4.8 onward
280 |
In Linux 4.8 the equivalency between /dev/urandom and /dev/random was
281 | given up. Now /dev/urandom output does not come from an entropy pool,
282 | but directly from a CSPRNG.
283 |
284 |
285 | Actual structure of the kernel’s random
286 | number generator from Linux 4.8 onward
287 |
288 |
Have you ever waited for /dev/random to give you more random numbers?
292 | Generating a PGP key inside a virtual machine maybe? Connecting to a web
293 | server that’s waiting for more random numbers to create an ephemeral
294 | session key?
295 |
That’s the problem. It inherently runs counter to availability. So
296 | your system is not working. It’s not doing what you built it to do.
297 | Obviously, that’s bad. You wouldn’t have built it if you didn’t need
298 | it.
299 |
But the problem runs even deeper: people don’t like to be stopped in
300 | their ways. They will devise workarounds, concoct bizarre machinations
301 | to just get it running. People who don’t know anything about
302 | cryptography. Normal people.
303 |
311 |
Why not patching out the call to random()? Why not having some guy in
312 | a web forum tell you how to use some strange ioctl to increase the
313 | entropy counter? Why not switch off SSL altogether?
314 |
In the end you just educate your users to do foolish things that
315 | compromise your system’s security without you ever knowing about it.
316 |
It’s easy to disregard availability, usability or other nice
317 | properties. Security trumps everything, right? So better be
318 | inconvenient, unavailable or unusable than feign security.
319 |
But that’s a false dichotomy. Blocking is not necessary for security.
320 | As we saw, /dev/urandom gives you
321 | the same kind of random numbers as /dev/random, straight out of a
322 | CSPRNG. Use it!
323 |
The CSPRNGs are alright
324 |
But now everything sounds really bleak. If even the high-quality
325 | random numbers from /dev/random are coming out of a CSPRNG, how can we
326 | use them for high-security purposes?
327 |
It turns out, that “looking random” is the basic requirement for a
328 | lot of our cryptographic building blocks. If you take the output of a
329 | cryptographic hash, it has to be indistinguishable from a random string
330 | so that cryptographers will accept it. If you take a block cipher, its
331 | output (without knowing the key) must also be indistinguishable from
332 | random data.
333 |
If anyone could gain an advantage over brute force breaking of
334 | cryptographic building blocks, using some perceived weakness of those
335 | CSPRNGs over “true” randomness, then it’s the same old story: you don’t
336 | have anything left. Block ciphers, hashes, everything is based on the
337 | same mathematical fundament as CSPRNGs. So don’t be afraid.
338 |
What about entropy running
339 | low?
340 |
It doesn’t matter.
341 |
The underlying cryptographic building blocks are designed such that
342 | an attacker cannot predict the outcome, as long as there was enough
343 | randomness (a.k.a. entropy) in the beginning. A usual lower limit for
344 | “enough” may be 256 bits. No more.
345 |
Considering that we were pretty hand-wavey about the term “entropy”
346 | in the first place, it feels right. As we saw, the kernel’s random
347 | number generator cannot even precisely know the amount of entropy
348 | entering the system. Only an estimate. And whether the model that’s the
349 | basis for the estimate is good enough is pretty unclear, too.
350 |
Re-seeding
351 |
But if entropy is so unimportant, why is fresh entropy constantly
352 | being injected into the random number generator?
353 |
First, it cannot hurt. If you’ve got more randomness just lying
354 | around, by all means use it!
355 |
359 |
There is another reason why re-seeding the random number generator
360 | every now and then is important:
361 |
Imagine an attacker knows everything about your random number
362 | generator’s internal state. That’s the most severe security compromise
363 | you can imagine, the attacker has full access to the system.
364 |
You’ve totally lost now, because the attacker can compute all future
365 | outputs from this point on.
366 |
But over time, with more and more fresh entropy being mixed into it,
367 | the internal state gets more and more random again. So that such a
368 | random number generator’s design is kind of self-healing.
369 |
But this is injecting entropy into the generator’s internal state, it
370 | has nothing to do with blocking its output.
371 |
The random and urandom man
372 | page
373 |
382 |
The man page for /dev/random and /dev/urandom is pretty effective
383 | when it comes to instilling fear into the gullible programmer’s
384 | mind:
385 |
386 | A read from the /dev/urandom device will not block waiting for more
387 | entropy. As a result, if there is not sufficient entropy in the entropy
388 | pool, the returned values are theoretically vulnerable to a
389 | cryptographic attack on the algorithms used by the driver. Knowledge of
390 | how to do this is not available in the current unclassified literature,
391 | but it is theoretically possible that such an attack may exist. If this
392 | is a concern in your application, use /dev/random instead.
393 |
394 |
Such an attack is not known in “unclassified literature”, but the NSA
395 | certainly has one in store, right? And if you’re really concerned about
396 | this (you should!), please use /dev/random, and all your problems are
397 | solved.
398 |
The truth is, while there may be such an attack available to secret
399 | services, evil hackers or the Bogeyman, it’s just not rational to just
400 | take it as a given.
401 |
And even if you need that peace of mind, let me tell you a secret: no
402 | practical attacks on AES, SHA-3 or other solid ciphers and hashes are
403 | known in the “unclassified” literature, either. Are you going to stop
404 | using those, as well? Of course not!
405 |
Now the fun part: “use /dev/random instead”. While /dev/urandom does
406 | not block, its random number output comes from the very same CSPRNG as
407 | /dev/random’s.
408 |
If you really need information-theoretically secure random numbers
409 | (you don’t!), and that’s about the only reason why the entropy of the
410 | CSPRNG’s input matters, you can’t use /dev/random, either!
411 |
The man page is silly, that’s all. At least it tries to redeem itself
412 | with this:
413 |
414 | If you are unsure about whether you should use /dev/random or
415 | /dev/urandom, then probably you want to use the latter. As a general
416 | rule, /dev/urandom should be used for everything except long-lived
417 | GPG/SSL/SSH keys.
418 |
419 |
428 |
Fine. I think it’s unnecessary, but if you want to use /dev/random
429 | for your “long-lived keys”, by all means, do so! You’ll be waiting a few
430 | seconds typing stuff on your keyboard, that’s no problem.
431 |
But please don’t make connections to a mail server hang forever, just
432 | because you “wanted to be safe”.
433 |
Orthodoxy
434 |
The view espoused here is certainly a tiny minority’s opinions on the
435 | Internet. But ask a real cryptographer, you’ll be hard pressed to find
436 | someone who sympathizes much with that blocking /dev/random.
Cryptographers are certainly not responsible for this superstitious
441 | nonsense. Think about this for a moment: whoever wrote the /dev/random
442 | manual page seems to simultaneously believe that
443 |
444 |
we can’t figure out how to deterministically expand one 256-bit
445 | /dev/random output into an endless stream of unpredictable keys (this is
446 | what we need from urandom), but
447 |
we can figure out how to use a single key to safely
448 | encrypt many messages (this is what we need from SSL, PGP,
449 | etc.).
450 |
451 | For a cryptographer this doesn’t even pass the laugh test.
452 |
453 |
Or Thomas
454 | Pornin, who is probably one of the most helpful persons I’ve ever
455 | encountered on the Stackexchange sites:
456 |
457 |
The short answer is yes. The long answer is also yes. /dev/urandom
458 | yields data which is indistinguishable from true randomness, given
459 | existing technology. Getting “better” randomness than what /dev/urandom
460 | provides is meaningless, unless you are using one of the few
461 | “information theoretic” cryptographic algorithm, which is not your case
462 | (you would know it).
463 | The man page for urandom is somewhat misleading, arguably downright
464 | wrong, when it suggests that /dev/urandom may “run out of entropy” and
465 | /dev/random should be preferred;
466 |
467 |
Or maybe Thomas
468 | Ptacek, who is not a real cryptographer in the sense of designing
469 | cryptographic algorithms or building cryptographic systems, but still
470 | the founder of a well-reputed security consultancy that’s doing a lot of
471 | penetration testing and breaking bad cryptography:
472 |
473 | Use urandom. Use urandom. Use urandom. Use urandom. Use urandom. Use
474 | urandom.
475 |
476 |
Not everything is perfect
477 |
/dev/urandom isn’t perfect. The problems are twofold:
478 |
On Linux, unlike FreeBSD, /dev/urandom never blocks. Remember that
479 | the whole security rested on some starting randomness, a seed?
480 |
Linux’s /dev/urandom happily gives you not-so-random numbers before
481 | the kernel even had the chance to gather entropy. When is that? At
482 | system start, booting the computer.
483 |
FreeBSD does the right thing: they don’t have the distinction between
484 | /dev/random and /dev/urandom, both are the same device. At startup
485 | /dev/random blocks once until enough starting entropy has been gathered.
486 | Then it won’t block ever again.
487 |
On Linux it isn’t too bad, because Linux distributions save some
488 | random numbers when booting up the system (but after they have gathered
489 | some entropy, since the startup script doesn’t run immediately after
490 | switching on the machine) into a seed file that is read next time the
491 | machine is booting. So you carry over the randomness from the last
492 | running of the machine.
493 |
Obviously that isn’t as good as if you let the shutdown scripts write
494 | out the seed, because in that case there would have been much more time
495 | to gather entropy. The advantage is obviously that this does not depend
496 | on a proper shutdown with execution of the shutdown scripts (in case the
497 | computer crashes, for example).
498 |
And it doesn’t help you the very first time a machine is running, but
499 | the Linux distributions usually do the same saving into a seed file when
500 | running the installer. So that’s mostly okay.
501 |
Virtual machines are the other problem. Because people like to clone
502 | them, or rewind them to a previously saved check point, this seed file
503 | doesn’t help you.
504 |
But the solution still isn’t using /dev/random everywhere, but
505 | properly seeding each and every virtual machine after cloning, restoring
506 | a checkpoint, whatever.